Skip to:
Content

BuddyPress.org

Changeset 4764


Ignore:
Timestamp:
07/21/2011 02:14:16 PM (13 years ago)
Author:
boonebgorges
Message:

Fixes sticky logic on group forum directories so that stickies always appear at the top of the order, without breaking pagination. Fixes #3059. Props sushkov for the inital patch. Introduces bp_forums_enable_global_directory_stickies() to allow easy modification of the default global forum directory behavior, which is to show group stickies in their normal freshness-based position.

Location:
trunk
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/bp-forums/bp-forums-functions.php

    r4709 r4764  
    8181        'page'          => 1,
    8282        'per_page'      => 15,
     83        'offset'    => false,
     84        'number'    => false,
    8385        'exclude'       => false,
    8486        'show_stickies' => 'all',
     
    9294        switch ( $type ) {
    9395            case 'newest':
    94                 $query = new BB_Query( 'topic', array( 'forum_id' => $forum_id, 'topic_author_id' => $user_id, 'per_page' => $per_page, 'page' => $page, 'number' => $per_page, 'exclude' => $exclude, 'topic_title' => $filter, 'sticky' => $show_stickies ), 'get_latest_topics' );
     96                $query = new BB_Query( 'topic', array( 'forum_id' => $forum_id, 'topic_author_id' => $user_id, 'per_page' => $per_page, 'page' => $page, 'number' => $per_page, 'exclude' => $exclude, 'topic_title' => $filter, 'sticky' => $show_stickies, 'offset' => $offset, 'number' => $number ), 'get_latest_topics' );
    9597                $topics =& $query->results;
    9698                break;
     
    491493
    492494/**
    493  * Returs the parent forum id for the bbPress abstraction layer
     495 * Returns the parent forum id for the bbPress abstraction layer
    494496 *
    495497 * @package BuddyPress
     
    500502function bp_forums_parent_forum_id() {
    501503    return apply_filters( 'bp_forums_parent_forum_id', BP_FORUMS_PARENT_FORUM_ID );
     504}
     505
     506/**
     507 * Should sticky topics be broken out of regular topic order on forum directories?
     508 *
     509 * Defaults to false. Define BP_FORUMS_ENABLE_GLOBAL_DIRECTORY_STICKIES, or filter
     510 * bp_forums_enable_global_directory_stickies, to change this behavior.
     511 *
     512 * @package BuddyPress
     513 * @since 1.3
     514 *
     515 * @return bool True if stickies should be displayed at the top of the global directory, false
     516 *    otherwise.
     517 */
     518function bp_forums_enable_global_directory_stickies() {
     519    return apply_filters( 'bp_forums_enable_global_directory_stickies', defined( 'BP_FORUMS_ENABLE_GLOBAL_DIRECTORY_STICKIES' ) && BP_FORUMS_ENABLE_GLOBAL_DIRECTORY_STICKIES );
    502520}
    503521
  • trunk/bp-forums/bp-forums-template.php

    r4757 r4764  
    6969    var $order;
    7070
    71     function BP_Forums_Template_Forum( $type, $forum_id, $user_id, $page, $per_page, $max, $no_stickies, $search_terms ) {
    72         $this->__construct( $type, $forum_id, $user_id, $page, $per_page, $max, $no_stickies, $search_terms );
    73     }
    74 
    75     function __construct( $type, $forum_id, $user_id, $page, $per_page, $max, $no_stickies, $search_terms ) {   
     71    function BP_Forums_Template_Forum( $type, $forum_id, $user_id, $page, $per_page, $max, $no_stickies, $search_terms, $offset = false, $number = false ) {
     72        $this->__construct( $type, $forum_id, $user_id, $page, $per_page, $max, $no_stickies, $search_terms, $offset, $number );
     73    }
     74
     75    function __construct( $type, $forum_id, $user_id, $page, $per_page, $max, $no_stickies, $search_terms, $offset = false, $number = false ) {
    7676        global $bp;
    7777
    78         $this->pag_page     = isset( $_REQUEST['p'] ) ? intval( $_REQUEST['p'] ) : $page;
    79         $this->pag_num      = isset( $_REQUEST['n'] ) ? intval( $_REQUEST['n'] ) : $per_page;
     78        $this->pag_page     = $page;
     79        $this->pag_num      = $per_page;
    8080        $this->type         = $type;
    8181        $this->search_terms = $search_terms;
    8282        $this->forum_id     = $forum_id;
     83        $this->offset       = $offset;
     84        $this->number       = $number;
    8385
    8486        switch ( $type ) {
    85             case 'newest': default:
    86                 $this->topics = bp_forums_get_forum_topics( array( 'user_id' => $user_id, 'forum_id' => $forum_id, 'filter' => $search_terms, 'page' => $this->pag_page, 'per_page' => $this->pag_num, 'show_stickies' => $no_stickies ) );
     87            case 'newest': default:             
     88                $this->topics = bp_forums_get_forum_topics( array( 'user_id' => $user_id, 'forum_id' => $forum_id, 'filter' => $search_terms, 'page' => $this->pag_page, 'per_page' => $this->pag_num, 'show_stickies' => $no_stickies, 'offset' => $offset, 'number' => $number ) );
    8789                break;
    8890
     
    112114                $topic_count = (int)groups_total_public_forum_topic_count( $type );
    113115            } else {
    114                 $topic_count = count( $this->topics );
     116                // For forum directories, get a true count
     117                $status = is_super_admin() ? 'all' : 'public'; // todo: member-of
     118                $topic_count = (int)groups_total_forum_topic_count( $status );
    115119            }
    116120
     
    120124                $this->total_topic_count = (int)$max;
    121125            }
    122 
     126           
    123127            if ( $max ) {
    124128                if ( $max >= count($this->topics) ) {
     
    134138        $this->topic_count       = apply_filters_ref_array( 'bp_forums_template_topic_count',                                 array( $this->topic_count, &$this->topics, $type, $forum_id, $per_page, $max, $no_stickies ) );
    135139        $this->total_topic_count = apply_filters_ref_array( 'bp_forums_template_total_topic_count', array( $this->total_topic_count, $this->topic_count, &$this->topics, $type, $forum_id, $per_page, $max, $no_stickies ) );
    136 
    137         if ( !$no_stickies ) {
    138             $stickies = array();
    139             $standard = array();
    140 
    141             // Place stickies at the top - not sure why bbPress doesn't do this?
    142             foreach( (array)$this->topics as $topic ) {
    143                 if ( isset( $topic->topic_sticky ) && 1 == (int)$topic->topic_sticky ) {
    144                     $stickies[] = $topic;
    145                 } else {
    146                     $standard[] = $topic;
    147                 }
    148             }
    149 
    150             $this->topics = array_merge( (array)$stickies, (array)$standard );
    151         }
    152140
    153141        // Fetch extra information for topics, so we don't have to query inside the loop
     
    213201}
    214202
     203/**
     204 * Initiate the forum topics loop.
     205 *
     206 * Like other BuddyPress custom loops, the default arguments for this function are determined
     207 * dynamically, depending on your current page. All of these $defaults can be overridden in the
     208 * $args parameter.
     209 *
     210 * @package BuddyPress
     211 * @uses apply_filters() Filter bp_has_topics to manipulate the $forums_template global before
     212 *   it's rendered, or to modify the value of has_topics().
     213 *
     214 * @param array $args See inline definition of $defaults for explanation of arguments
     215 * @return bool Returns true when forum topics are found corresponding to the args, false otherwise.
     216 */
    215217function bp_has_forum_topics( $args = '' ) {
    216218    global $forum_template, $bp;
     
    225227    $forum_id     = false;
    226228    $search_terms = false;
    227     $no_stickies  = 'all';
     229    $do_stickies  = true;
    228230
    229231    // User filtering
     
    255257    if ( bp_is_directory() && !empty( $_GET['fs'] ) )
    256258        $search_terms = $_GET['fs'];
    257 
    258     // Show stickies on a group forum
    259     if ( isset( $bp->groups->current_group ) )
    260         $no_stickies = null;
     259   
     260    // Get the pagination arguments from $_REQUEST
     261    $page     = isset( $_REQUEST['p'] ) ? intval( $_REQUEST['p'] ) : 1;
     262    $per_page = isset( $_REQUEST['n'] ) ? intval( $_REQUEST['n'] ) : 20;
     263   
     264    // Unless set otherwise, stickies appear in normal order on the global forum directory
     265    if ( bp_is_directory() && bp_is_forums_component() && !bp_forums_enable_global_directory_stickies() )
     266        $do_stickies = false;
    261267
    262268    $defaults = array(
     
    264270        'forum_id'     => $forum_id,
    265271        'user_id'      => $user_id,
    266         'page'         => 1,
    267         'per_page'     => 20,
     272        'page'         => $page,
     273        'per_page'     => $per_page,
    268274        'max'          => false,
    269         'no_stickies'  => $no_stickies,
    270         'search_terms' => $search_terms
     275        'number'       => false,
     276        'offset'       => false,
     277        'search_terms' => $search_terms,
     278        'do_stickies'  => $do_stickies
    271279    );
    272280
     
    280288        $type = 'tags';
    281289    }
    282 
    283     $forum_template = new BP_Forums_Template_Forum( $type, $forum_id, $user_id, $page, $per_page, $max, $no_stickies, $search_terms );
     290   
     291    /** Sticky logic ******************************************************************/
     292   
     293    if ( $do_stickies ) {
     294        // Fetch the stickies
     295        $stickies_template = new BP_Forums_Template_Forum( $type, $forum_id, $user_id, 0, 0, $max, 'sticky', $search_terms );
     296       
     297        // If stickies are found, try merging them
     298        if ( $stickies_template->has_topics() ) {
     299       
     300            // If stickies are for current $page       
     301            $page_start_num = ( ( $page - 1 ) * $per_page ) + 1;
     302            $page_end_num   = $page * $per_page <= $stickies_template->total_topic_count ? $page * $per_page : $stickies_template->total_topic_count;
     303           
     304            // Calculate the number of sticky topics that will be shown on this page
     305            if ( $stickies_template->topic_count < $page_start_num ) {
     306                $this_page_stickies = 0;
     307            } else {           
     308                $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
     309               
     310                // $this_page_stickies cannot be more than $per_page or less than 0
     311                if ( $this_page_stickies > $per_page )
     312                    $this_page_stickies = $per_page;
     313                else if ( $this_page_stickies < 0 )
     314                    $this_page_stickies = 0;
     315            }
     316           
     317            // Calculate the total number of topics that will be shown on this page
     318            $this_page_topics = $stickies_template->total_topic_count >= ( $page * $per_page ) ? $per_page : $page_end_num - ( $page_start_num - 1 );
     319           
     320            // If the number of stickies to be shown is less than $per_page, fetch some
     321            // non-stickies to fill in the rest
     322            if ( $this_page_stickies < $this_page_topics ) {
     323                // How many non-stickies do we need?
     324                $non_sticky_number = $this_page_topics - $this_page_stickies;
     325               
     326                // Calculate the non-sticky offset         
     327                // How many non-stickies on all pages up to this point?
     328                $non_sticky_total = $page_end_num - $stickies_template->topic_count;
     329               
     330                // The offset is the number of total non-stickies, less the number
     331                // to be shown on this page
     332                $non_sticky_offset = $non_sticky_total - $non_sticky_number;
     333               
     334                // Fetch the non-stickies
     335                $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 );
     336               
     337                // If there are stickies to merge on this page, do it now
     338                if ( $this_page_stickies ) {
     339                    // Correct the topic_count
     340                    $forum_template->topic_count += (int)$this_page_stickies;
     341                   
     342                    // Figure out which stickies need to be included
     343                    $this_page_sticky_topics = array_slice( $stickies_template->topics, 0 - $this_page_stickies );
     344                   
     345                    // Merge these topics into the forum template
     346                    $forum_template->topics = array_merge( $this_page_sticky_topics, (array)$forum_template->topics );
     347                }
     348            } else {
     349                // This page has no non-stickies
     350                $forum_template = $stickies_template;
     351               
     352                // Adjust the topic count and trim the topics
     353                $forum_template->topic_count = $this_page_stickies;
     354                $forum_template->topics      = array_slice( $forum_template->topics, $page - 1 );   
     355            }
     356                   
     357            // Because we're using a manual offset and number for the topic query, we
     358            // must set the page number manually, and recalculate the pagination links
     359            $forum_template->pag_num     = $per_page;
     360            $forum_template->pag_page    = $page;
     361           
     362            $forum_template->pag_links = paginate_links( array(
     363                'base'      => add_query_arg( array( 'p' => '%#%', 'n' => $forum_template->pag_num ) ),
     364                'format'    => '',
     365                'total'     => ceil( (int)$forum_template->total_topic_count / (int)$forum_template->pag_num ),
     366                'current'   => $forum_template->pag_page,
     367                'prev_text' => '&larr;',
     368                'next_text' => '&rarr;',
     369                'mid_size'  => 1
     370            ) );
     371           
     372        } else {
     373            // Fetch the non-sticky topics if no stickies were found
     374            $forum_template = new BP_Forums_Template_Forum( $type, $forum_id, $user_id, $page, $per_page, $max, 'all', $search_terms );
     375        }
     376    } else {
     377        // When skipping the sticky logic, just pull up the forum topics like usual
     378        $forum_template = new BP_Forums_Template_Forum( $type, $forum_id, $user_id, $page, $per_page, $max, 'all', $search_terms );
     379    }
     380       
    284381    return apply_filters( 'bp_has_topics', $forum_template->has_topics(), $forum_template );
    285382}
  • trunk/bp-groups/bp-groups-classes.php

    r4649 r4764  
    596596        return $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(id) FROM {$bp->groups->table_name_members} WHERE group_id = %d AND is_confirmed = 1 AND is_banned = 0", $group_id ) );
    597597    }
     598   
     599   
     600    /**
     601     * Get a total count of all topics of a given status, across groups/forums
     602     *
     603     * @package BuddyPress
     604     * @since 1.3
     605     *
     606     * @param str $status 'public', 'private', 'hidden', 'all' Which group types to count
     607     * @return int The topic count
     608     */
     609    function get_global_topic_count( $status = 'public' ) {
     610        global $bbdb, $wpdb, $bp;
     611       
     612        switch ( $status ) {
     613            case 'all' :
     614                $status_sql = '';
     615                break;
     616               
     617            case 'hidden' :
     618                $status_sql = $wpdb->prepare( "AND g.status = 'hidden'" );
     619                break;
     620               
     621            case 'private' :
     622                $status_sql = $wpdb->prepare( "AND g.status = 'private'" );
     623                break;
     624               
     625            case 'public' :
     626            default :
     627                $status_sql = $wpdb->prepare( "AND g.status = 'public'" );
     628                break;
     629        }
     630       
     631        return $wpdb->get_var( "SELECT COUNT(t.topic_id) FROM {$bbdb->topics} AS t INNER JOIN {$bp->groups->table_name_groupmeta} AS gm ON t.forum_id = gm.meta_value INNER JOIN {$bp->groups->table_name} AS g ON gm.group_id = g.id WHERE gm.meta_key = 'forum_id' {$status_sql} AND t.topic_status = '0' AND t.topic_sticky != '2' " );
     632    }
    598633}
    599634
  • trunk/bp-groups/bp-groups-forums.php

    r4684 r4764  
    245245}
    246246
    247 
    248247function groups_total_public_forum_topic_count( $type = 'newest' ) {
    249248    return apply_filters( 'groups_total_public_forum_topic_count', BP_Groups_Group::get_global_forum_topic_count( $type ) );
    250249}
    251250
     251/**
     252 * Get a total count of all topics of a given status, across groups/forums
     253 *
     254 * @package BuddyPress
     255 * @since 1.3
     256 *
     257 * @param str $status 'public', 'private', 'hidden', 'all' Which group types to count
     258 * @return int The topic count
     259 */
     260function groups_total_forum_topic_count( $status = 'public' ) {
     261    return apply_filters( 'groups_total_forum_topic_count', BP_Groups_Group::get_global_topic_count( $status ) );
     262}
     263
    252264?>
Note: See TracChangeset for help on using the changeset viewer.