/** * Delete a topic. * * @param AUTO_LINK The ID of the topic to delete. * @param LONG_TEXT The reason for this action . * @param ?AUTO_LINK Where topic to move posts in this topic to (NULL: delete the posts). * @return AUTO_LINK The forum ID the topic is in (could be found without calling the function, but as we've looked it up, it is worth keeping). */ function ocf_delete_topic($topic_id, $reason = '', $post_target_topic_id = NULL) { // Info about source $info = $GLOBALS['FORUM_DB']->query_select('f_topics', array('t_pt_to', 't_pt_from', 't_cache_first_title', 't_cache_first_member_id', 't_poll_id', 't_forum_id', 't_cache_num_posts', 't_validated'), array('id' => $topic_id)); if (!array_key_exists(0, $info)) { warn_exit(do_lang_tempcode('MISSING_RESOURCE')); } $name = $info[0]['t_cache_first_title']; $poll_id = $info[0]['t_poll_id']; $forum_id = $info[0]['t_forum_id']; $num_posts = $info[0]['t_cache_num_posts']; $validated = $info[0]['t_validated']; if (!ocf_may_delete_topics_by($forum_id, get_member(), $info[0]['t_cache_first_member_id']) || !is_null($info[0]['t_pt_from']) && $info[0]['t_pt_from'] != get_member() && (!is_null($info[0]['t_pt_to']) && $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($post_target_topic_id)) { $to = $GLOBALS['FORUM_DB']->query_value_null_ok('f_topics', 't_forum_id', array('id' => $post_target_topic_id)); if (is_null($to)) { warn_exit(do_lang_tempcode('MISSING_RESOURCE')); } } if (!is_null($forum_id)) { // 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) $forum_id) . (!is_null($post_target_topic_id) ? ' OR id=' . strval((int) $to) : ''), 2); if ($post_count_info[0]['id'] == $forum_id) { $from_cnt = $post_count_info[0]['f_post_count_increment']; $to_cnt = array_key_exists(1, $post_count_info) ? $post_count_info[1]['f_post_count_increment'] : 0; } 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 p_topic_id=' . strval((int) $topic_id); 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_cnt == 0) { $member_post_count = -$member_post_count; } ocf_force_update_member_post_count($member_id, $member_post_count); } } } // What to do with our posts if (!is_null($post_target_topic_id)) { $GLOBALS['FORUM_DB']->query_update('f_posts', array('p_cache_forum_id' => $to, 'p_topic_id' => $post_target_topic_id), array('p_topic_id' => $topic_id)); require_code('ocf_posts_action2'); ocf_force_update_topic_cacheing($post_target_topic_id); if (!is_null($forum_id)) { ocf_force_update_forum_cacheing($forum_id, $to, 1, $num_posts); } } else { $_postdetails = $GLOBALS['FORUM_DB']->query('SELECT p_post FROM ' . $GLOBALS['FORUM_DB']->get_table_prefix() . 'f_posts WHERE p_topic_id=' . strval((int) $topic_id)); foreach ($_postdetails as $post) { delete_lang($post['p_post'], $GLOBALS['FORUM_DB']); } $GLOBALS['FORUM_DB']->query_delete('f_posts', array('p_topic_id' => $topic_id)); } // Delete stuff if (!is_null($poll_id)) { require_code('ocf_polls_action'); require_code('ocf_polls_action2'); ocf_delete_poll($poll_id, ''); } $GLOBALS['FORUM_DB']->query_delete('f_topics', array('id' => $topic_id), '', 1); $GLOBALS['FORUM_DB']->query_delete('f_read_logs', array('l_topic_id' => $topic_id)); require_code('notifications'); delete_all_notifications_on('ocf_topics', strval($topic_id)); // Delete the ticket row if it's a ticket if (addon_installed('tickets')) { require_code('tickets'); if (!is_null($forum_id) && is_ticket_forum($forum_id)) { require_code('tickets2'); delete_ticket_by_topic_id($topic_id); } } // Update forum view cacheing if (!is_null($forum_id)) { require_code('ocf_posts_action2'); ocf_force_update_forum_cacheing($forum_id, $validated == 0 ? 0 : -1, -$num_posts); } require_code('ocf_general_action2'); ocf_mod_log_it('DELETE_TOPIC', strval($topic_id), $name, $reason); if (!is_null($forum_id)) { require_code('ocf_posts_action'); ocf_decache_ocp_blocks($forum_id); } else { decache('side_ocf_personal_topics'); decache('_new_pp'); } return $forum_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; }