Example #1
0
 /**
  * Standard modular run function for attachment hooks. They see if permission to an attachment of an ID relating to this content is present for the current member.
  *
  * @param  ID_TEXT		The ID
  * @param  object			The database connection to check on
  * @return boolean		Whether there is permission
  */
 function run($id, $connection)
 {
     if (get_forum_type() != 'ocf') {
         return false;
     }
     // Shouldn't be here, but maybe it's left over somehow
     require_code('ocf_forums');
     require_code('ocf_topics');
     $info = $GLOBALS['FORUM_DB']->query_select('f_posts', array('p_cache_forum_id', 'p_intended_solely_for', 'p_poster', 'p_topic_id'), array('id' => intval($id)), '', 1);
     if (!array_key_exists(0, $info)) {
         return false;
     }
     $forum_id = $info[0]['p_cache_forum_id'];
     $poster = $info[0]['p_poster'];
     $forum_id_parent = is_null($forum_id) ? NULL : $GLOBALS['FORUM_DB']->query_value('f_forums', 'f_parent_forum', array('id' => $forum_id));
     $forum_id_parent_parent = is_null($forum_id_parent) ? NULL : $GLOBALS['FORUM_DB']->query_value('f_forums', 'f_parent_forum', array('id' => $forum_id_parent));
     $intended_solely_for = $info[0]['p_intended_solely_for'];
     if (!is_null($intended_solely_for) && $poster != get_member() && $intended_solely_for != get_member()) {
         return false;
     }
     if (is_null($forum_id)) {
         $topic_info = $GLOBALS['FORUM_DB']->query_select('f_topics', array('t_pt_to', 't_pt_from'), array('id' => $info[0]['p_topic_id']), '', 1);
         return $topic_info[0]['t_pt_to'] == get_member() || $topic_info[0]['t_pt_from'] == get_member() || ocf_has_special_pt_access($info[0]['p_topic_id']);
     }
     if (addon_installed('tickets')) {
         $tf = get_option('ticket_forum_name', true);
         if (!is_null($tf)) {
             $forum2 = $GLOBALS['FORUM_DRIVER']->forum_id_from_name($tf);
         } else {
             $forum2 = NULL;
         }
         if ($forum2 === $forum_id || $forum2 === $forum_id_parent || $forum2 === $forum_id_parent_parent) {
             $title = $GLOBALS['FORUM_DB']->query_value('f_topics', 't_cache_first_title', array('id' => $info[0]['p_topic_id']));
             if (substr($title, 0, strlen(strval(get_member())) + 1) == strval(get_member()) . '_') {
                 return true;
             }
             require_lang('tickets');
             $description = $GLOBALS['FORUM_DB']->query_value('f_topics', 't_description', array('id' => $info[0]['p_topic_id']));
             if (substr($description, 0, strlen(do_lang('SUPPORT_TICKET') . ': #' . strval(get_member())) + 1) == do_lang('SUPPORT_TICKET') . ': #' . strval(get_member()) . '_') {
                 return true;
             }
         }
     }
     return has_category_access(get_member(), 'forums', strval($forum_id));
 }
/**
 * 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);
}
Example #3
0
/**
 * Given a particular bit of feedback content, check if the user may access it.
 *
 * @param  MEMBER			User to check
 * @param  ID_TEXT		Content type
 * @param  ID_TEXT		Content ID
 * @return boolean		Whether there is permission
 */
function may_view_content_behind_feedback_code($member_id, $content_type, $content_id)
{
    require_code('content');
    $permission_type_code = convert_ocportal_type_codes('feedback_type_code', $content_type, 'permissions_type_code');
    $module = convert_ocportal_type_codes('feedback_type_code', $content_type, 'module');
    if ($module == '') {
        $module = $content_id;
    }
    $category_id = mixed();
    $award_hook = convert_ocportal_type_codes('feedback_type_code', $content_type, 'award_hook');
    if ($award_hook != '') {
        require_code('hooks/systems/awards/' . $award_hook);
        $award_hook_ob = object_factory('Hook_awards_' . $award_hook);
        $info = $award_hook_ob->info();
        if (isset($info['category_field'])) {
            $cma_hook = convert_ocportal_type_codes('award_hook', $award_hook, 'cma_hook');
            list(, , , $content) = content_get_details($cma_hook, $content_id);
            if (!is_null($content)) {
                $category_field = $info['category_field'];
                if (is_array($category_field)) {
                    $category_field = array_pop($category_field);
                    $category_id = is_integer($content[$category_field]) ? strval($content[$category_field]) : $content[$category_field];
                    if ($award_hook == 'catalogue_entry') {
                        $catalogue_name = $GLOBALS['SITE_DB']->query_value('catalogue_categories', 'c_name', array('id' => $category_id));
                        if (!has_category_access($member_id, 'catalogues_catalogue', $catalogue_name)) {
                            return false;
                        }
                    }
                } else {
                    $category_id = is_integer($content[$category_field]) ? strval($content[$category_field]) : $content[$category_field];
                }
            }
        }
    }
    // FUDGEFUDGE: Extra check for private topics
    $topic_id = NULL;
    if ($content_type == 'post' && get_forum_type() == 'ocf') {
        $post_rows = $GLOBALS['FORUM_DB']->query_select('f_posts', array('p_topic_id', 'p_intended_solely_for', 'p_poster'), array('id' => intval($content_id)), '', 1);
        if (!array_key_exists(0, $post_rows)) {
            return false;
        }
        if ($post_rows[0]['p_intended_solely_for'] !== NULL && ($post_rows[0]['p_intended_solely_for'] != $member_id && $post_rows[0]['p_poster'] != $member_id || is_guest($member_id))) {
            return false;
        }
        $topic_id = $post_rows[0]['p_topic_id'];
    }
    if ($content_type == 'topic' && get_forum_type() == 'ocf') {
        $topic_id = intval($content_id);
    }
    if (!is_null($topic_id)) {
        $topic_rows = $GLOBALS['FORUM_DB']->query_select('f_topics', array('t_forum_id', 't_pt_from', 't_pt_to'), array('id' => $topic_id), '', 1);
        if (!array_key_exists(0, $topic_rows)) {
            return false;
        }
        require_code('ocf_topics');
        if ($topic_rows[0]['t_forum_id'] == NULL && ($topic_rows[0]['t_pt_from'] != $member_id && $topic_rows[0]['t_pt_to'] != $member_id && !ocf_has_special_pt_access($topic_id, $member_id) || is_guest($member_id))) {
            return false;
        }
    }
    return has_actual_page_access($member_id, $module) && ($permission_type_code == '' || is_null($category_id) || has_category_access($member_id, $permission_type_code, $category_id));
}
Example #4
0
 /**
  * Get a list of members who have enabled this notification (i.e. have permission to AND have chosen to or are defaulted to).
  *
  * @param  ID_TEXT		Notification code
  * @param  ?SHORT_TEXT	The category within the notification code (NULL: none)
  * @param  ?array			List of member IDs we are restricting to (NULL: no restriction). This effectively works as a intersection set operator against those who have enabled.
  * @param  integer		Start position (for pagination)
  * @param  integer		Maximum (for pagination)
  * @return array			A pair: Map of members to their notification setting, and whether there may be more
  */
 function list_members_who_have_enabled($notification_code, $category = NULL, $to_member_ids = NULL, $start = 0, $max = 300)
 {
     if (!is_numeric($category) && !is_null($category)) {
         warn_exit(do_lang_tempcode('INTERNAL_ERROR'));
     }
     // We should never be accessing as forum:<id>, that is used only behind the scenes
     list($members, $maybe_more) = $this->_all_members_who_have_enabled($notification_code, $category, $to_member_ids, $start, $max);
     if (is_numeric($category)) {
         $forum_details = $GLOBALS['FORUM_DB']->query_select('f_topics', array('t_forum_id', 't_pt_from', 't_pt_to'), array('id' => intval($category)));
         if (!array_key_exists(0, $forum_details)) {
             return array(array(), false);
         }
         // Topic deleted already?
         $forum_id = $forum_details[0]['t_forum_id'];
         if (!is_null($forum_id)) {
             list($members2, $maybe_more2) = $this->_all_members_who_have_enabled($notification_code, 'forum:' . strval($forum_id), $to_member_ids, $start, $max);
             $members += $members2;
             $maybe_more = $maybe_more || $maybe_more2;
         } else {
             require_code('ocf_topics');
             $members_new = $members;
             foreach ($members as $member_id => $setting) {
                 if ($forum_details[0]['t_pt_from'] == $member_id || $forum_details[0]['t_pt_to'] == $member_id || ocf_has_special_pt_access(intval($category), $member_id) || !has_specific_permission($member_id, 'view_other_pt')) {
                     $members_new[$member_id] = $setting;
                 }
             }
             $members = $members_new;
         }
     } else {
         $forum_id = intval(substr($category, 6));
     }
     if (!is_null($forum_id)) {
         list($members, $maybe_more) = $this->_all_members_who_have_enabled_with_zone_access(array($members, $maybe_more), 'forum', $notification_code, $category, $to_member_ids, $start, $max);
         list($members, $maybe_more) = $this->_all_members_who_have_enabled_with_category_access(array($members, $maybe_more), 'forums', $notification_code, strval($forum_id), $to_member_ids, $start, $max);
     }
     // We know PTs have been pre-filtered before notification is sent out, to limit them
     return array($members, $maybe_more);
 }
Example #5
0
 /**
  * Check there is at least some moderation access over the given topic.
  *
  * @param  AUTO_LINK		The topic ID
  */
 function check_has_mod_access($topic_id)
 {
     $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'));
     }
     $forum_id = $topic_info[0]['t_forum_id'];
     $personal_topic = is_null($forum_id);
     if ($personal_topic && $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');
     }
     if (!$personal_topic) {
         if (!has_category_access(get_member(), 'forums', strval($forum_id))) {
             access_denied('I_ERROR');
         }
     }
 }
Example #6
0
/**
 * 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;
}
Example #7
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;
}