/** * Find whether a member may attach a poll to a detailed topic. * * @param AUTO_LINK The topic. * @param ?MEMBER The topic owner (NULL: ask the DB for it). * @param ?boolean Whether the topic already has a poll (NULL: ask the DB for it). * @param ?MEMBER The forum the topic is in (NULL: ask the DB for it). * @param ?MEMBER The member we are checking for (NULL: current member). * @return boolean The answer. */ function ocf_may_attach_poll($topic_id, $topic_owner = NULL, $has_poll_already = NULL, $forum_id = NULL, $member_id = NULL) { if (is_null($topic_owner)) { $topic_info = $GLOBALS['FORUM_DB']->query_select('f_topics', array('*'), array('id' => $topic_id), '', 1); if (!array_key_exists(0, $topic_info)) { warn_exit(do_lang_tempcode('MISSING_RESOURCE')); } $topic_owner = $topic_info[0]['t_cache_first_member_id']; $has_poll_already = !is_null($topic_info[0]['t_poll_id']); $forum_id = $topic_info[0]['t_forum_id']; } if (is_null($member_id)) { $member_id = get_member(); } if ($has_poll_already) { return false; } if ($topic_owner == $member_id && !is_guest($member_id)) { return true; } if (ocf_may_moderate_forum($forum_id, $member_id)) { return true; } return false; }
/** * Whether a certain member may perform multi moderations in a certain forum. * * @param AUTO_LINK The forum. * @param ?MEMBER The member (NULL: current member). * @return boolean Answer. */ function ocf_may_perform_multi_moderation($forum_id, $member_id = NULL) { if (is_null($member_id)) { $member_id = get_member(); } if (!ocf_may_moderate_forum($forum_id, $member_id)) { return false; } return has_specific_permission($member_id, 'run_multi_moderations'); }
/** * Add a topic. * * @param ?AUTO_LINK The ID of the forum the topic will be in (NULL: Private Topic). * @param SHORT_TEXT Description of the topic. * @param SHORT_TEXT The theme image code of the emoticon for the topic. * @param ?BINARY Whether the topic is validated (NULL: detect whether it should be). * @param BINARY Whether the topic is open. * @param BINARY Whether the topic is pinned. * @param BINARY Whether the topic is sunk. * @param BINARY Whether the topic is cascading. * @param ?MEMBER If it is a Private Topic, who is it 'from' (NULL: not a Private Topic). * @param ?MEMBER If it is a Private Topic, who is it 'to' (NULL: not a Private Topic). * @param boolean Whether to check the poster has permissions for the given topic settings. * @param integer The number of times the topic has been viewed. * @param ?AUTO_LINK Force an ID (NULL: don't force an ID) * @param SHORT_TEXT Link related to the topic (e.g. link to view a ticket). * @return AUTO_LINK The ID of the newly created topic. */ function ocf_make_topic($forum_id, $description = '', $emoticon = '', $validated = NULL, $open = 1, $pinned = 0, $sunk = 0, $cascading = 0, $pt_from = NULL, $pt_to = NULL, $check_perms = true, $num_views = 0, $id = NULL, $description_link = '') { if (is_null($pinned)) { $pinned = 0; } if (is_null($sunk)) { $sunk = 0; } if (is_null($description)) { $description = ''; } if (is_null($num_views)) { $num_views = 0; } if ($check_perms) { require_code('ocf_topics'); if (!ocf_may_post_topic($forum_id, get_member())) { access_denied('I_ERROR'); } if (!is_null($pt_to)) { decache('side_ocf_personal_topics', array($pt_to)); decache('_new_pp', array($pt_to)); } if (!is_null($forum_id)) { require_code('ocf_posts_action'); ocf_decache_ocp_blocks($forum_id); } require_code('ocf_forums'); if (!ocf_may_moderate_forum($forum_id)) { $pinned = 0; $sunk = 0; $open = 1; $cascading = 0; } } if (is_null($validated) || $check_perms && $validated == 1) { if (!is_null($forum_id) && !has_specific_permission(get_member(), 'bypass_validation_midrange_content', 'topics', array('forums', $forum_id))) { $validated = 0; } else { $validated = 1; } } if (!addon_installed('unvalidated')) { $validated = 1; } $map = array('t_pinned' => $pinned, 't_sunk' => $sunk, 't_cascading' => $cascading, 't_forum_id' => $forum_id, 't_pt_from' => $pt_from, 't_pt_to' => $pt_to, 't_description' => substr($description, 0, 255), 't_description_link' => substr($description_link, 0, 255), 't_emoticon' => $emoticon, 't_num_views' => $num_views, 't_validated' => $validated, 't_is_open' => $open, 't_poll_id' => NULL, 't_cache_first_post_id' => NULL, 't_cache_first_post' => NULL, 't_cache_first_time' => NULL, 't_cache_first_title' => '', 't_cache_first_username' => '', 't_cache_first_member_id' => NULL, 't_cache_last_post_id' => NULL, 't_cache_last_time' => NULL, 't_cache_last_title' => '', 't_cache_last_username' => '', 't_cache_last_member_id' => NULL, 't_cache_num_posts' => 0, 't_pt_from_category' => '', 't_pt_to_category' => ''); if (!is_null($id)) { $map['id'] = $id; } return $GLOBALS['FORUM_DB']->query_insert('f_topics', $map, true); }
/** * Move some topics. * * @param AUTO_LINK The forum the topics are currently in. * @param AUTO_LINK The forum the topics are being moved to. * @param ?array A list of the topic IDs to move (NULL: move all topics from source forum). */ function ocf_move_topics($from, $to, $topics = NULL) { if ($from == $to) { return; } // That would be nuts, and interfere with our logic require_code('notifications'); require_code('ocf_topics'); require_code('ocf_forums_action2'); $forum_name = ocf_ensure_forum_exists($to); if (!ocf_may_moderate_forum($from)) { access_denied('I_ERROR'); } $topic_count = 0; if (is_null($topics)) { if (is_null($from)) { access_denied('I_ERROR'); } $all_topics = $GLOBALS['FORUM_DB']->query_select('f_topics', array('id', 't_cache_num_posts', 't_validated'), array('t_forum_id' => $from)); $or_list = ''; $post_count = 0; $topics = array(); foreach ($all_topics as $topic_info) { $topics[] = $topic_info['id']; if ($or_list != '') { $or_list .= ' OR '; } $or_list .= 'id=' . strval((int) $topic_info['id']); $post_count += $topic_info['t_cache_num_posts']; if ($topic_info['t_validated'] == 1) { $topic_count++; } } $GLOBALS['FORUM_DB']->query_update('f_topics', array('t_forum_id' => $to), array('t_forum_id' => $from)); // Update forum IDs' for posts $GLOBALS['FORUM_DB']->query_update('f_posts', array('p_cache_forum_id' => $to), array('p_cache_forum_id' => $from)); $or_list_2 = str_replace('id', 'p_topic_id', $or_list); if ($or_list_2 == '') { return; } } elseif (count($topics) == 1) { $topic_info = $GLOBALS['FORUM_DB']->query_select('f_topics', array('t_forum_id', 't_pt_from', 't_pt_to', 't_cache_first_title', 't_cache_num_posts', 't_validated'), array('id' => $topics[0])); if (!array_key_exists(0, $topic_info)) { warn_exit(do_lang_tempcode('MISSING_RESOURCE')); } if ($topic_info[0]['t_forum_id'] != $from || $topic_info[0]['t_pt_from'] != get_member() && $topic_info[0]['t_pt_to'] != get_member() && !ocf_has_special_pt_access($topics[0]) && !has_specific_permission(get_member(), 'view_other_pt') && is_null($topic_info[0]['t_forum_id'])) { access_denied('I_ERROR'); } if ($topic_info[0]['t_validated'] == 1) { $topic_count++; } $topic_title = $topic_info[0]['t_cache_first_title']; $post_count = $topic_info[0]['t_cache_num_posts']; $GLOBALS['FORUM_DB']->query_update('f_topics', array('t_pt_from' => NULL, 't_pt_to' => NULL, 't_forum_id' => $to), array('t_forum_id' => $from, 'id' => $topics[0]), '', 1); // Extra where constraint for added security log_it('MOVE_TOPICS', $topic_title, strval($topics[0])); $or_list = 'id=' . strval($topics[0]); $or_list_2 = 'p_topic_id=' . strval($topics[0]); // Update forum IDs' for posts $GLOBALS['FORUM_DB']->query_update('f_posts', array('p_cache_forum_id' => $to), array('p_topic_id' => $topics[0])); } else { if (count($topics) == 0) { return; } // Nuts, lol $or_list = ''; foreach ($topics as $topic_id) { if ($or_list != '') { $or_list .= ' OR '; } $or_list .= 'id=' . strval((int) $topic_id); if (is_null($from)) { $topic_info = $GLOBALS['FORUM_DB']->query_select('f_topics', array('t_forum_id', 't_pt_from', 't_pt_to'), array('id' => $topic_id)); if (array_key_exists(0, $topic_info)) { if ($topic_info[0]['t_validated'] == 1) { $topic_count++; } if ($topic_info[0]['t_forum_id'] != $from || $topic_info[0]['t_pt_from'] != get_member() && $topic_info[0]['t_pt_to'] != get_member() && !ocf_has_special_pt_access($topic_id) && !has_specific_permission(get_member(), 'view_other_pt')) { access_denied('I_ERROR'); } } } else { $topic_count++; // Might not be validated, which means technically we shouldn't do this, but it's low chance, low impact, and the indicator is only a cache thing anyway } } $GLOBALS['FORUM_DB']->query('UPDATE ' . $GLOBALS['FORUM_DB']->get_table_prefix() . 'f_topics SET t_forum_id=' . strval((int) $to) . ',t_pt_from=NULL,t_pt_to=NULL WHERE t_forum_id' . (is_null($from) ? ' IS NULL' : '=' . strval((int) $from)) . ' AND (' . $or_list . ')'); log_it('MOVE_TOPICS', do_lang('MULTIPLE')); $post_count = $GLOBALS['FORUM_DB']->query_value_null_ok_full('SELECT SUM(t_cache_num_posts) FROM ' . $GLOBALS['FORUM_DB']->get_table_prefix() . 'f_topics WHERE ' . $or_list); // Update forum IDs' for posts $or_list_2 = str_replace('id', 'p_topic_id', $or_list); $GLOBALS['FORUM_DB']->query('UPDATE ' . $GLOBALS['FORUM_DB']->get_table_prefix() . 'f_posts SET p_cache_forum_id=' . strval((int) $to) . ' WHERE ' . $or_list_2); } require_code('ocf_posts_action2'); // Update source forum cache view if (!is_null($from)) { ocf_force_update_forum_cacheing($from, -$topic_count, -$post_count); } // Update dest forum cache view ocf_force_update_forum_cacheing($to, $topic_count, $post_count); if (!is_null($from)) { // Update member post counts if we've switched between post-count countable forums $post_count_info = $GLOBALS['FORUM_DB']->query('SELECT id,f_post_count_increment FROM ' . $GLOBALS['FORUM_DB']->get_table_prefix() . 'f_forums WHERE id=' . strval((int) $from) . ' OR id=' . strval((int) $to), 2); if ($post_count_info[0]['id'] == $from) { $from_cnt = $post_count_info[0]['f_post_count_increment']; $to_cnt = $post_count_info[1]['f_post_count_increment']; } else { $from_cnt = $post_count_info[1]['f_post_count_increment']; $to_cnt = $post_count_info[0]['f_post_count_increment']; } require_code('ocf_posts_action'); if ($from_cnt != $to_cnt) { $sql = 'SELECT p_poster FROM ' . $GLOBALS['FORUM_DB']->get_table_prefix() . 'f_posts WHERE (' . $or_list_2 . ')'; if (addon_installed('unvalidated')) { $sql .= ' AND p_validated=1'; } $_member_post_counts = collapse_1d_complexity('p_poster', $GLOBALS['FORUM_DB']->query($sql)); $member_post_counts = array_count_values($_member_post_counts); foreach ($member_post_counts as $member_id => $member_post_count) { if ($to == 0) { $member_post_count = -$member_post_count; } ocf_force_update_member_post_count($member_id, $member_post_count); } } } require_code('ocf_posts_action'); if (!is_null($from)) { ocf_decache_ocp_blocks($from); } else { decache('side_ocf_personal_topics'); decache('_new_pp'); } ocf_decache_ocp_blocks($to, $forum_name); if (function_exists('set_time_limit')) { @set_time_limit(0); } $start = 0; do { $topics2 = $GLOBALS['FORUM_DB']->query('SELECT id,t_cache_first_title,t_cache_last_time FROM ' . $GLOBALS['FORUM_DB']->get_table_prefix() . 'f_topics WHERE ' . $or_list, 100, $start); require_code('urls2'); foreach ($topics2 as $_topic) { if ($_topic['t_cache_last_time'] < time() - 60 * 60 * 24 * 14) { continue; } $topic_id = $_topic['id']; $topic_title = $_topic['t_cache_first_title']; suggest_new_idmoniker_for('topicview', 'misc', strval($topic_id), $topic_title); // Now lets inform people tracking the topic that it has moved $subject = do_lang('TOPIC_MOVE_MAIL_SUBJECT', get_site_name(), $topic_title); $mail = do_lang('TOPIC_MOVE_MAIL', comcode_escape(get_site_name()), comcode_escape($topic_title), array(comcode_escape($forum_name))); dispatch_notification('ocf_topic', strval($topic_id), $subject, $mail); } } while (count($topics2) == 100); }
/** * The actualiser to make a normal topic a Private Topic. * * @return tempcode The UI */ function _make_personal() { $topic_id = post_param_integer('id'); $forum_id = $GLOBALS['FORUM_DB']->query_value_null_ok('f_topics', 't_forum_id', array('id' => $topic_id)); if (is_null($forum_id)) { warn_exit(do_lang_tempcode('MISSING_RESOURCE')); } if (!ocf_may_moderate_forum($forum_id, get_member())) { access_denied('I_ERROR'); } $_a = post_param('a'); $_b = post_param('b'); $a = $GLOBALS['FORUM_DRIVER']->get_member_from_username($_a); if (is_null($a)) { warn_exit(do_lang_tempcode('_USER_NO_EXIST', $_a)); } $b = $GLOBALS['FORUM_DRIVER']->get_member_from_username($_b); if (is_null($b)) { warn_exit(do_lang_tempcode('_USER_NO_EXIST', $_b)); } $GLOBALS['FORUM_DB']->query_update('f_topics', array('t_pt_from' => $a, 't_pt_to' => $b, 't_forum_id' => NULL), array('id' => $topic_id), '', 1); // Update forum cache view require_code('ocf_posts_action2'); ocf_force_update_forum_cacheing($forum_id, -1); return $this->redirect_to('MAKE_PERSONAL', $topic_id); }
/** * 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; }
/** * Add a post. * * @param AUTO_LINK The ID of the topic to add the post to. * @param SHORT_TEXT The title of the post (may be blank). * @param LONG_TEXT The post. * @param BINARY Whether to skip showing the posters signature in the post. * @param boolean Whether the post is the first in the topic. * @param ?BINARY Whether the post is validated (NULL: unknown, find whether it needs to be marked unvalidated initially). * @param BINARY Whether the post is marked emphasised. * @param ?string The name of the person making the post (NULL: username of current member). * @param ?IP The IP address the post is to be made under (NULL: IP of current user). * @param ?TIME The time of the post (NULL: now). * @param ?MEMBER The poster (NULL: current member). * @param ?MEMBER The member that this post is intended solely for (NULL: public). * @param ?TIME The last edit time of the post (NULL: never edited). * @param ?MEMBER The member that was last to edit the post (NULL: never edited). * @param boolean Whether to check permissions for whether the post may be made as it is given. * @param boolean Whether to update the caches after making the post. * @param ?AUTO_LINK The forum the post will be in (NULL: find out from the DB). * @param boolean Whether to allow attachments in this post. * @param ?string The title of the topic (NULL: find from the DB). * @param BINARY Whether the topic is a sunk topic. * @param ?AUTO_LINK Force an ID (NULL: don't force an ID) * @param boolean Whether to make the post anonymous * @param boolean Whether to skip post checks * @param boolean Whether this is for a new Private Topic * @param boolean Whether to explicitly insert the Comcode with admin privileges * @param ?AUTO_LINK Parent post ID (NULL: none-threaded/root-of-thread) * @return AUTO_LINK The ID of the new post. */ function ocf_make_post($topic_id, $title, $post, $skip_sig = 0, $is_starter = false, $validated = NULL, $is_emphasised = 0, $poster_name_if_guest = NULL, $ip_address = NULL, $time = NULL, $poster = NULL, $intended_solely_for = NULL, $last_edit_time = NULL, $last_edit_by = NULL, $check_permissions = true, $update_cacheing = true, $forum_id = NULL, $support_attachments = true, $topic_title = '', $sunk = 0, $id = NULL, $anonymous = false, $skip_post_checks = false, $is_pt = false, $insert_comcode_as_admin = false, $parent_id = NULL) { if (is_null($poster)) { $poster = get_member(); } if ($check_permissions) { if (strlen($title) > 120) { warn_exit(do_lang_tempcode('TITLE_TOO_LONG')); } if (get_option('prevent_shouting') == '1') { if (strtoupper($title) == $title) { $title = ucwords($title); } } if (is_null($intended_solely_for) && !$skip_post_checks) { ocf_check_post($post, $topic_id, $poster); } } if (is_null($ip_address)) { $ip_address = get_ip_address(); } if (is_null($time)) { $time = time(); $send_notification = true; } else { $send_notification = false; } if (is_null($poster_name_if_guest)) { if ($poster == $GLOBALS['OCF_DRIVER']->get_guest_id() || $anonymous) { $poster_name_if_guest = do_lang('GUEST'); } else { $poster_name_if_guest = $GLOBALS['OCF_DRIVER']->get_username($poster); if (is_null($poster_name_if_guest)) { $poster_name_if_guest = do_lang('UNKNOWN'); } } } if (is_null($forum_id) || $topic_title == '' && !$is_starter) { $info = $GLOBALS['FORUM_DB']->query_select('f_topics', array('t_is_open', 't_pt_from', 't_pt_to', 't_forum_id', 't_cache_last_member_id', 't_cache_first_title'), array('id' => $topic_id), '', 1); if (!array_key_exists(0, $info)) { warn_exit(do_lang_tempcode('MISSING_RESOURCE')); } $forum_id = $info[0]['t_forum_id']; $topic_title = $info[0]['t_cache_first_title']; if ($topic_title == '') { $topic_title = $title; } if ($check_permissions) { if ($info[0]['t_pt_from'] != get_member() && $info[0]['t_pt_to'] != get_member() && !ocf_has_special_pt_access($topic_id) && !has_specific_permission(get_member(), 'view_other_pt') && is_null($forum_id)) { access_denied('I_ERROR'); } } } if (is_null($forum_id)) { if ($check_permissions && $poster == $GLOBALS['OCF_DRIVER']->get_guest_id()) { access_denied('I_ERROR'); } $validated = 1; // Personal posts always validated } else { if ($check_permissions) { if ($info[0]['t_is_open'] == 0 && !ocf_may_moderate_forum($forum_id)) { access_denied('I_ERROR'); } $last_member_id = $info[0]['t_cache_last_member_id']; if (!ocf_may_post_in_topic($forum_id, $topic_id, $last_member_id) && !$is_starter) { access_denied('I_ERROR'); } } } // Ensure parent post is from the same topic if (!is_null($parent_id)) { $test_topic_id = $GLOBALS['FORUM_DB']->query_value_null_ok('f_posts', 'p_topic_id', array('id' => $parent_id), ' AND ' . ocf_get_topic_where($topic_id, $poster)); if (is_null($test_topic_id)) { $parent_id = NULL; } } if (is_null($validated) || $validated == 1 && $check_permissions) { if (!is_null($forum_id) && !has_specific_permission(get_member(), 'bypass_validation_lowrange_content', 'topics', array('forums', $forum_id))) { $validated = 0; } else { $validated = 1; } } if (!$support_attachments) { $lang_id = insert_lang_comcode($post, 4, $GLOBALS['FORUM_DB'], $insert_comcode_as_admin); } else { $lang_id = 0; } if (!addon_installed('unvalidated')) { $validated = 1; } $map = array('p_title' => substr($title, 0, 255), 'p_post' => $lang_id, 'p_ip_address' => $ip_address, 'p_time' => $time, 'p_poster' => $anonymous ? db_get_first_id() : $poster, 'p_poster_name_if_guest' => substr($poster_name_if_guest, 0, 80), 'p_validated' => $validated, 'p_topic_id' => $topic_id, 'p_is_emphasised' => $is_emphasised, 'p_cache_forum_id' => $forum_id, 'p_last_edit_time' => $last_edit_time, 'p_last_edit_by' => $last_edit_by, 'p_intended_solely_for' => $intended_solely_for, 'p_skip_sig' => $skip_sig, 'p_parent_id' => $parent_id); if (!is_null($id)) { $map['id'] = $id; } $post_id = $GLOBALS['FORUM_DB']->query_insert('f_posts', $map, true); if ($support_attachments) { require_code('attachments2'); $lang_id = insert_lang_comcode_attachments(4, $post, 'ocf_post', strval($post_id), $GLOBALS['FORUM_DB']); $GLOBALS['FORUM_DB']->query_update('f_posts', array('p_post' => $lang_id), array('id' => $post_id), '', 1); } $_url = build_url(array('page' => 'topicview', 'type' => 'findpost', 'id' => $post_id), 'forum', NULL, false, false, true, 'post_' . strval($post_id)); $url = $_url->evaluate(); if ($validated == 0) { if ($check_permissions) { // send_validation_mail is used for other content - but forum is special $subject = do_lang('POST_REQUIRING_VALIDATION_MAIL_SUBJECT', $topic_title, NULL, NULL, get_site_default_lang()); $post_text = get_translated_text($lang_id, $GLOBALS['FORUM_DB'], get_site_default_lang()); $mail = do_lang('POST_REQUIRING_VALIDATION_MAIL', comcode_escape($url), comcode_escape($poster_name_if_guest), $post_text); require_code('notifications'); dispatch_notification('needs_validation', NULL, $subject, $mail); } } else { if ($check_permissions) { if ($send_notification) { $post_comcode = get_translated_text($lang_id, $GLOBALS['FORUM_DB']); require_code('ocf_posts_action2'); ocf_send_topic_notification($url, $topic_id, $forum_id, $anonymous ? db_get_first_id() : $poster, $is_starter, $post_comcode, $topic_title, $intended_solely_for, $is_pt); // Send a notification for the inline PP if (!is_null($intended_solely_for)) { require_code('notifications'); $msubject = do_lang('NEW_PERSONAL_POST_SUBJECT', $topic_title, NULL, NULL, get_lang($intended_solely_for)); $mmessage = do_lang('NEW_PERSONAL_POST_MESSAGE', comcode_escape($GLOBALS['FORUM_DRIVER']->get_username($anonymous ? db_get_first_id() : $poster)), comcode_escape($topic_title), array(comcode_escape($url), $post_comcode), get_lang($intended_solely_for)); dispatch_notification('ocf_new_pt', NULL, $msubject, $mmessage, array($intended_solely_for), $anonymous ? db_get_first_id() : $poster); } } } } if ($check_permissions) { // Is the user gonna automatically enable notifications for this? $auto_monitor_contrib_content = $GLOBALS['OCF_DRIVER']->get_member_row_field($poster, 'm_auto_monitor_contrib_content'); if ($auto_monitor_contrib_content == 1) { require_code('notifications'); enable_notifications('ocf_topic', strval($topic_id), $poster); } } if ($update_cacheing) { if (function_exists('get_member')) { if (function_exists('ocf_ping_topic_read')) { ocf_ping_topic_read($topic_id); } if (is_null($forum_id)) { $with = $info[0]['t_pt_from']; if ($with == get_member()) { $with = $info[0]['t_pt_to']; } decache('side_ocf_personal_topics', array($with)); decache('_new_pp', array($with)); } if (get_option('show_post_validation') == '1') { decache('main_staff_checklist'); } } if (is_null($intended_solely_for)) { if ($validated == 1) { require_code('ocf_posts_action2'); ocf_force_update_topic_cacheing($topic_id, 1, true, $is_starter, $post_id, $time, $title, $lang_id, $poster_name_if_guest, $poster); } if ($validated == 1) { if (!is_null($forum_id)) { require_code('ocf_posts_action2'); // Find if the topic is validated. This can be approximate, if we don't get 1 then ocf_force_update_forum_cacheing will do a search, making the code very slightly slower if (!$check_permissions || is_null($forum_id)) { $topic_validated = 1; } else { if ($is_starter) { $topic_validated = has_specific_permission($poster, 'bypass_validation_midrange_content', 'topics', array('forums', $forum_id)) ? 1 : 0; } else { $topic_validated = $GLOBALS['FORUM_DB']->query_value('f_topics', 't_validated', array('id' => $topic_id)); } } ocf_force_update_forum_cacheing($forum_id, $is_starter ? 1 : 0, 1, $topic_validated == 0 ? NULL : $topic_id, $topic_validated == 0 ? NULL : $topic_title, $topic_validated == 0 ? NULL : $time, $topic_validated == 0 ? NULL : $poster_name_if_guest, $topic_validated == 0 ? NULL : $poster, $topic_validated == 0 ? NULL : $forum_id); } } } // Update post count if (!is_null($forum_id)) { $post_counts = is_null($forum_id) ? 1 : $GLOBALS['FORUM_DB']->query_value_null_ok('f_forums', 'f_post_count_increment', array('id' => $forum_id)); if ($post_counts === 1 && !$anonymous && $validated == 1) { ocf_force_update_member_post_count($poster, 1); } if ($check_permissions) { ocf_decache_ocp_blocks($forum_id, NULL, $intended_solely_for); } // i.e. we don't run this if in installer } if ($poster != $GLOBALS['OCF_DRIVER']->get_guest_id()) { require_code('ocf_posts_action2'); ocf_member_handle_promotion($poster); } } return $post_id; }
/** * 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; }
/** * Move posts from one topic to another. * * @param AUTO_LINK The ID of the source topic. * @param AUTO_LINK The ID of the destination topic. * @param array A list of post IDs to move. * @param LONG_TEXT The reason for this action. * @param ?AUTO_LINK The forum the destination topic is in (NULL: find from DB). * @param boolean Whether to delete the topic if all posts in it have been moved. * @param ?SHORT_TEXT The title for the new topic (NULL: work out / irrelevant). * @return boolean Whether the topic was deleted. */ function ocf_move_posts($from_topic_id, $to_topic_id, $posts, $reason, $to_forum_id = NULL, $delete_if_empty = false, $title = NULL) { if (is_null($to_topic_id)) { if (is_null($to_forum_id)) { fatal_exit(do_lang_tempcode('INTERNAL_ERROR')); } require_code('ocf_topics_action'); $to_topic_id = ocf_make_topic($to_forum_id); if (!is_null($title) && count($posts) != 0) { $GLOBALS['FORUM_DB']->query_update('f_posts', array('p_title' => $title), array('id' => $posts[0]), '', 1); } } // Info about source $from_info = $GLOBALS['FORUM_DB']->query_select('f_topics', array('t_forum_id'), array('id' => $from_topic_id)); if (!array_key_exists(0, $from_info)) { warn_exit(do_lang_tempcode('MISSING_RESOURCE')); } $from_forum_id = $from_info[0]['t_forum_id']; $to_info = $GLOBALS['FORUM_DB']->query_select('f_topics', array('t_forum_id'), array('id' => $to_topic_id)); if (!array_key_exists(0, $to_info)) { warn_exit(do_lang_tempcode('MISSING_RESOURCE')); } $to_forum_id = $to_info[0]['t_forum_id']; $or_list = ''; foreach ($posts as $post) { if ($or_list != '') { $or_list .= ' OR '; } $or_list .= 'id=' . strval((int) $post); } // Check access if (!ocf_may_moderate_forum($from_forum_id)) { access_denied('I_ERROR'); } $_postdetails = $GLOBALS['FORUM_DB']->query('SELECT p_cache_forum_id,p_intended_solely_for,p_validated FROM ' . $GLOBALS['FORUM_DB']->get_table_prefix() . 'f_posts WHERE ' . $or_list); $num_posts_counted = 0; foreach ($_postdetails as $post) { if (is_null($post['p_intended_solely_for']) && $post['p_validated'] == 1) { $num_posts_counted++; } if ($post['p_cache_forum_id'] != $from_forum_id) { fatal_exit(do_lang_tempcode('INTERNAL_ERROR')); } } $GLOBALS['FORUM_DB']->query('UPDATE ' . $GLOBALS['FORUM_DB']->get_table_prefix() . 'f_posts SET p_cache_forum_id=' . strval((int) $to_forum_id) . ', p_topic_id=' . strval((int) $to_topic_id) . ' WHERE ' . $or_list); // Update cacheing require_code('ocf_posts_action2'); ocf_force_update_topic_cacheing($from_topic_id, -$num_posts_counted, true, true); ocf_force_update_topic_cacheing($to_topic_id, $num_posts_counted, true, true); if (!is_null($from_forum_id) && !is_null($to_topic_id) && $from_forum_id != $to_topic_id) { if ($from_forum_id != $to_forum_id) { require_code('ocf_forums_action2'); ocf_force_update_forum_cacheing($from_forum_id, 0, -$num_posts_counted); ocf_force_update_forum_cacheing($to_forum_id, 0, $num_posts_counted); // Update member post counts if we've switched between post-count countable forums $post_count_info = $GLOBALS['FORUM_DB']->query('SELECT id,f_post_count_increment FROM ' . $GLOBALS['FORUM_DB']->get_table_prefix() . 'f_forums WHERE id=' . strval((int) $from_forum_id) . ' OR id=' . strval((int) $to_forum_id), 2); if ($post_count_info[0]['id'] == $from_forum_id) { $from = $post_count_info[0]['f_post_count_increment']; $to = $post_count_info[1]['f_post_count_increment']; } else { $from = $post_count_info[1]['f_post_count_increment']; $to = $post_count_info[0]['f_post_count_increment']; } if ($from != $to) { $sql = 'SELECT p_poster FROM ' . $GLOBALS['FORUM_DB']->get_table_prefix() . 'f_posts WHERE (' . $or_list . ')'; if (addon_installed('unvalidated')) { $sql .= ' AND p_validated=1'; } $_member_post_counts = collapse_1d_complexity('p_poster', $GLOBALS['FORUM_DB']->query($sql)); $member_post_counts = array_count_values($_member_post_counts); foreach ($member_post_counts as $member_id => $member_post_count) { if ($to == 0) { $member_post_count = -$member_post_count; } ocf_force_update_member_post_count($member_id, $member_post_count); } } } } $test = $delete_if_empty ? $GLOBALS['FORUM_DB']->query_value('f_posts', 'COUNT(*)', array('p_topic_id' => $from_topic_id)) : 1; if ($test == 0) { $num_view_count = 0; $num_view_count += $GLOBALS['FORUM_DB']->query_value('f_topics', 't_num_views', array('id' => $from_topic_id)); $num_view_count += $GLOBALS['FORUM_DB']->query_value('f_topics', 't_num_views', array('id' => $to_topic_id)); $GLOBALS['FORUM_DB']->query_update('f_topics', array('t_num_views' => $num_view_count), array('id' => $to_topic_id), '', 1); require_code('ocf_topics_action'); require_code('ocf_topics_action2'); ocf_delete_topic($from_topic_id, do_lang('MOVE_POSTS')); return true; } else { // Make informative post $me_link = '[page="' . get_module_zone('members') . '" type="view" id="' . strval(get_member()) . '" caption="' . $GLOBALS['OCF_DRIVER']->get_username(get_member()) . '"]members[/page]'; $topic_title = $GLOBALS['FORUM_DB']->query_value('f_topics', 't_cache_first_title', array('id' => $to_topic_id)); $lang = do_lang('INLINE_POSTS_MOVED_MESSAGE', $me_link, integer_format(count($posts)), array('[page="' . get_module_zone('topicview') . '" id="' . strval($to_topic_id) . '" caption="' . str_replace('"', '\\"', str_replace('[', '\\[', $topic_title)) . '"]topicview[/page]')); ocf_make_post($from_topic_id, '', $lang, 0, false, 1, 1, NULL, NULL, $GLOBALS['FORUM_DB']->query_value('f_posts', 'p_time', array('id' => $posts[0])) + 1, NULL, NULL, NULL, NULL, false); require_code('ocf_general_action2'); ocf_mod_log_it('MOVE_POSTS', strval($to_topic_id), strval(count($posts)), $reason); if (!is_null($from_forum_id)) { ocf_decache_ocp_blocks($from_forum_id); } if (!is_null($to_forum_id)) { ocf_decache_ocp_blocks($to_forum_id); } return false; } return false; // should never get here }