/**
 * Initiate the forum topics loop.
 *
 * Like other BuddyPress custom loops, the default arguments for this function
 * are determined dynamically, depending on your current page. All of these
 * $defaults can be overridden in the $args parameter.
 *
 * @uses apply_filters() Filter 'bp_has_topics' to manipulate the
 *       $forums_template global before it's rendered, or to modify the value
 *       of has_topics().
 *
 * @param array $args {
 *     Arguments for limiting the contents of the forum topics loop.
 *
 *     @type string $type The 'type' is the sort order/kind. 'newest',
 *           'popular', 'unreplied', 'tags'. Default: 'newest'.
 *     @type int $forum_id The ID of the forum for which topics are being
 *           queried. Default: the ID of the forum belonging to the current
 *           group, if available.
 *     @type int $user_id The ID of a user to whom to limit results. If viewing
 *           a member's profile, defaults to that member's ID; otherwise
 *           defaults to 0.
 *     @type int $page The number of the page being requested. Default: 1, or
 *           the value of $_GET['p'].
 *     @type int $per_pag The number items to return per page. Default: 20, or
 *           the value of $_GET['n'].
 *     @type int $max Optional. Max records to return. Default: false (no max).
 *     @type int $number Optional. Number of records to return. Default: false.
 *     @type int $offset Optional. Offset results by a given value.
 *           Default: false.
 *     @type string $search_terms Optional. A string to which results should be
 *           limited. Default: false, or the value of $_GET['fs'].
 *     @type string|bool $do_stickies Whether to move stickies to the top of
 *           the sort order. Default: true if looking at a group forum,
 *           otherwise false.
 * }
 * @return bool True when forum topics are found corresponding to the args,
 *         false otherwise.
 */
function bp_has_forum_topics($args = '')
{
    global $forum_template, $bp;
    /***
     * Set the defaults based on the current page. Any of these will be overridden
     * if arguments are directly passed into the loop. Custom plugins should always
     * pass their parameters directly to the loop.
     */
    $type = 'newest';
    $user_id = 0;
    $forum_id = false;
    $search_terms = false;
    $do_stickies = false;
    // User filtering
    if (bp_displayed_user_id()) {
        $user_id = bp_displayed_user_id();
    }
    // "Replied" query must be manually modified
    if ('replies' == bp_current_action()) {
        $user_id = 0;
        // User id must be handled manually by the filter, not by BB_Query
        add_filter('get_topics_distinct', 'bp_forums_add_replied_distinct_sql', 20);
        add_filter('get_topics_join', 'bp_forums_add_replied_join_sql', 20);
        add_filter('get_topics_where', 'bp_forums_add_replied_where_sql', 20);
    }
    // If we're in a single group, set this group's forum_id
    if (!$forum_id && !empty($bp->groups->current_group)) {
        $bp->groups->current_group->forum_id = groups_get_groupmeta($bp->groups->current_group->id, 'forum_id');
        // If it turns out there is no forum for this group, return false so
        // we don't fetch all global topics
        if (empty($bp->groups->current_group->forum_id)) {
            return false;
        }
        $forum_id = $bp->groups->current_group->forum_id;
    }
    // If $_GET['fs'] is set, let's auto populate the search_terms var
    if (bp_is_directory() && !empty($_GET['fs'])) {
        $search_terms = $_GET['fs'];
    }
    // Get the pagination arguments from $_REQUEST
    $page = isset($_REQUEST['p']) ? intval($_REQUEST['p']) : 1;
    $per_page = isset($_REQUEST['n']) ? intval($_REQUEST['n']) : 20;
    // By default, stickies are only pushed to the top of the order on individual group forums
    if (bp_is_group_forum()) {
        $do_stickies = true;
    }
    $defaults = array('type' => $type, 'forum_id' => $forum_id, 'user_id' => $user_id, 'page' => $page, 'per_page' => $per_page, 'max' => false, 'number' => false, 'offset' => false, 'search_terms' => $search_terms, 'do_stickies' => $do_stickies);
    $r = bp_parse_args($args, $defaults, 'has_forum_topics');
    extract($r);
    // If we're viewing a tag URL in the directory, let's override the type and
    // set it to tags and the filter to the tag name
    if (bp_is_current_action('tag') && ($search_terms = bp_action_variable(0))) {
        $type = 'tags';
    }
    /** Sticky logic ******************************************************************/
    if ($do_stickies) {
        // Fetch the stickies
        $stickies_template = new BP_Forums_Template_Forum($type, $forum_id, $user_id, 0, 0, $max, 'sticky', $search_terms);
        // If stickies are found, try merging them
        if ($stickies_template->has_topics()) {
            // If stickies are for current $page
            $page_start_num = ($page - 1) * $per_page + 1;
            $page_end_num = $page * $per_page <= $stickies_template->total_topic_count ? $page * $per_page : $stickies_template->total_topic_count;
            // Calculate the number of sticky topics that will be shown on this page
            if ($stickies_template->topic_count < $page_start_num) {
                $this_page_stickies = 0;
            } else {
                $this_page_stickies = $stickies_template->topic_count - $per_page * floor($stickies_template->topic_count / $per_page) * ($page - 1);
                // Total stickies minus sticky count through this page
                // $this_page_stickies cannot be more than $per_page or less than 0
                if ($this_page_stickies > $per_page) {
                    $this_page_stickies = $per_page;
                } else {
                    if ($this_page_stickies < 0) {
                        $this_page_stickies = 0;
                    }
                }
            }
            // Calculate the total number of topics that will be shown on this page
            $this_page_topics = $stickies_template->total_topic_count >= $page * $per_page ? $per_page : $page_end_num - ($page_start_num - 1);
            // If the number of stickies to be shown is less than $per_page, fetch some
            // non-stickies to fill in the rest
            if ($this_page_stickies < $this_page_topics) {
                // How many non-stickies do we need?
                $non_sticky_number = $this_page_topics - $this_page_stickies;
                // Calculate the non-sticky offset
                // How many non-stickies on all pages up to this point?
                $non_sticky_total = $page_end_num - $stickies_template->topic_count;
                // The offset is the number of total non-stickies, less the number
                // to be shown on this page
                $non_sticky_offset = $non_sticky_total - $non_sticky_number;
                // Fetch the non-stickies
                $forum_template = new BP_Forums_Template_Forum($type, $forum_id, $user_id, 1, $per_page, $max, 'no', $search_terms, $non_sticky_offset, $non_sticky_number);
                // If there are stickies to merge on this page, do it now
                if ($this_page_stickies) {
                    // Correct the topic_count
                    $forum_template->topic_count += (int) $this_page_stickies;
                    // Figure out which stickies need to be included
                    $this_page_sticky_topics = array_slice($stickies_template->topics, 0 - $this_page_stickies);
                    // Merge these topics into the forum template
                    $forum_template->topics = array_merge($this_page_sticky_topics, (array) $forum_template->topics);
                }
            } else {
                // This page has no non-stickies
                $forum_template = $stickies_template;
                // Adjust the topic count and trim the topics
                $forum_template->topic_count = $this_page_stickies;
                $forum_template->topics = array_slice($forum_template->topics, $page - 1);
            }
            // Because we're using a manual offset and number for the topic query, we
            // must set the page number manually, and recalculate the pagination links
            $forum_template->pag_num = $per_page;
            $forum_template->pag_page = $page;
            $forum_template->pag_links = paginate_links(array('base' => add_query_arg(array('p' => '%#%', 'n' => $forum_template->pag_num)), 'format' => '', 'total' => ceil((int) $forum_template->total_topic_count / (int) $forum_template->pag_num), 'current' => $forum_template->pag_page, 'prev_text' => _x('&larr;', 'Forum topic pagination previous text', 'buddypress'), 'next_text' => _x('&rarr;', 'Forum topic pagination next text', 'buddypress'), 'mid_size' => 1));
        } else {
            // Fetch the non-sticky topics if no stickies were found
            $forum_template = new BP_Forums_Template_Forum($type, $forum_id, $user_id, $page, $per_page, $max, 'all', $search_terms);
        }
    } else {
        // When skipping the sticky logic, just pull up the forum topics like usual
        $forum_template = new BP_Forums_Template_Forum($type, $forum_id, $user_id, $page, $per_page, $max, 'all', $search_terms);
    }
    return apply_filters('bp_has_topics', $forum_template->has_topics(), $forum_template);
}
function bp_has_topics($args = '')
{
    global $forum_template, $bp;
    global $group_obj;
    $defaults = array('forum_id' => false, 'per_page' => 10, 'max' => false);
    $r = wp_parse_args($args, $defaults);
    extract($r, EXTR_SKIP);
    if (!$forum_id && $bp->current_component == $bp->groups->slug && 'forum' == $bp->current_action) {
        $forum_id = groups_get_groupmeta($group_obj->id, 'forum_id');
    }
    if (is_numeric($forum_id)) {
        $forum_template = new BP_Forums_Template_Forum($forum_id, $per_page, $max);
    } else {
        return false;
    }
    return $forum_template->has_topics();
}