• I have spent a lot of time searching for a way to restrict the bbPress forums based on User Rank. I found a lot of topics asking for this, but I could not find any solutions.

    In the end, I decided to write my own plugin to solve this (seemed like a fun challenge) that is based on Members plugin. I thought that it would be good to share with others that have the same issue I did.

    As the disclaimer says, this is my first plugin. I started working with WordPress about 2 or 3 weeks ago, therefore it may not be the best written plugin, but it works.

    http://www.tehnik-design.com/bbpress-forum-permissions/

    In case this topic should go else where, let me know. Since it is based on Members plugin and there are a few topics here asking about bbPress I feel that is is a good fit.

    http://wordpress.org/extend/plugins/members/

Viewing 12 replies - 1 through 12 (of 12 total)
  • thanks ezakiel, this is something badly needed by bbpress community 🙂

    would this also work with user role editor wp plugin ?

    http://wordpress.org/extend/plugins/user-role-editor/

    Thread Starter Aleksandar Adamovic

    (@ezakiel)

    User Role Editor and Members are fundamentally different. URE is used to manage the capabilities of users and roles (create new roles..etc), while Members plugin manages which roles can see which posts.

    Any roles you do create with URE will be usable with Members plugin and the extension I wrote. The new roles will appear in Content Permissions when creating new forums. Check the roles you want to have access to the forum, and thats it.

    This is GREAT ! Spend like 8 hours implementing this myself, just didnt wrap it into a plugin. Could you maybe add filtering on topics as well, so that the topic widgets and bbp_has_topics works as well ?

    Thread Starter Aleksandar Adamovic

    (@ezakiel)

    Sure, should be fairly simple to implement. I have to an update to have it support filtering the BuddyPress activity stream, I will use that time to look at implementing filtering for topics as well.

    Subscribe to this topic or my site. I will post once I update the plugin. The update should be done sometime next week.

    If enough people are interested, I might make this an actual plugin on WordPress downloads.

    actual plugin on wp directory would be a great idea, this functionality is a BIG missing piece of the bbpress puzzle, restricting forum access by groups is a standard feature of phpbb etc

    but, i’m having some probs getting this to work properly on a test site i’ve been hacking away at, i am using members, URE & s2Members as well, prob time for yet another caps reset, need more time for testing on my end

    from what i understand, all of these plugins are fairly common on elaborate bbpress sites w multiple roles, and a working plugin for restricting forum>topic>reply access by wordpress/bbpress user roles currently does not exist but would be very popular i think 🙂

    ideally, a stand alone plugin which does not require but will work alongside the other plugins i mentioned above, just a metabox in admin area on edit forum page listing roles and read/write yes/no radio buttons should do it ?

    prob a good idea to start to topic on bbpress forums too, get feedback form bbpress devs and more users etc

    http://bbpress.org/forums/

    thanks again 🙂

    sam

    boom, after a bit more testing this is working great alongside s2members, URE & members, so we finally have private groups by user role in bbpress 🙂

    thanks again, looking forward to seeing this developed further, filtering topics etc as above

    Did you get to fixing the topics ?

    Thread Starter Aleksandar Adamovic

    (@ezakiel)

    I started looking at it. Yesterday I released an update that fixed the issue with BuddyPress and activity feed. That was higher priority since it showed the actual post content vs just the title.

    I had to reinstall my PC so I lost a lot of time. I am hoping to release the topic filtering soon.

    Subscribe to my site (email or rss) as I will be posting updates through there. Once I implement all the necessary filtering and make it so that it is not dependent on Members plugin I will be releasing it to WordPress plugin repository.

    Something is wrong with your site. I cant comment.. But the location of the topics query is here

    \wp-content\plugins\bbpress\includes\topics\template-tags.php:

    bbp_has_topics. I have already begun this but with very mediocre results, i cant control ordering somehow and it shows stickies regardles of choice.. I had to make a custom function to not interfeer with normal behavior.

    function tehnik_bpp_get_permitted_topics($topic_list)
    {
        if(function_exists('members_can_user_view_post'))
        {
            $filtered_topics = array();
    
            //Get Current User ID
            $user_id = wp_get_current_user()->ID;
    
            foreach ($topic_list as $topic)
            {
                $topic_id = $topic->ID;
    
                $forum_id = bbp_get_topic_forum_id($topic_id);
    
                if(members_can_user_view_post($user_id, $forum_id))
                {
                    array_push($filtered_topics, $topic_id);
                }
            }
    
            return (array) $filtered_topics;
        }
    
        return true;
    }
    
    function tehnik_bpp_get_permitted_topic_ids($topic_query)
    {
        //Check if Members plugin function exists. No need to reinvent the wheel..use what is available
        if (!function_exists('members_can_user_view_post')) return array();
    
        //Get Current User ID
        $user_id = wp_get_current_user()->ID;
    
        //Init the Array which will hold our list of allowed forums
        $allowed_topics = array();
    
        //Loop through all the forums
        while ( $topic_query->have_posts() ) :
            $topic_query->the_post();
    
            //Get the Forum/Post ID
            $topic_id = $topic_query->post->ID;
            $forum_id = bbp_get_topic_forum_id($topic_id);
    
            //Check if User has permissions to view this Post ID
            if(members_can_user_view_post($user_id, $forum_id))
            {
                //User can view this post (forum) - add it to the allowed forums array
                array_push($allowed_topics, $topic_id);
            }
    
        endwhile;
    
        //Return the list
    
        return $allowed_topics;
    }
    
    /**
         * This function filters the list of forums based on the users rank as set by the Mebmers plugin
         */
        function bbp_has_topics_custom( $args = '' ){
            global $wp_rewrite;
    
        /** Defaults **************************************************************/
    
        // Other defaults
        $default_topic_search  = !empty( $_REQUEST['ts'] ) ? $_REQUEST['ts'] : false;
        $default_show_stickies = false;
        $default_post_parent   = 'any';
    
        // Default argument array
        $meta_query =  array(
            'post_type'      => bbp_get_topic_post_type(), // Narrow query down to bbPress topics
            'post_parent'    => $default_post_parent,      // Forum ID
            's'              => $default_topic_search,     // Topic Search
            'show_stickies'  => false,    // Ignore sticky topics?
            'max_num_pages'  => false,                     // Maximum number of pages to show
        );
    
        //Get an array of IDs which the current user has permissions to view
        $allowed_topics = tehnik_bpp_get_permitted_topic_ids(new WP_Query($meta_query));
    
        // Default argument array
        $default = array(
            'post_type'      => bbp_get_topic_post_type(), // Narrow query down to bbPress topics
            'post_parent'    => $default_post_parent,      // Forum ID
            'meta_key'       => '_bbp_last_active_time',   // Make sure topic has some last activity time
            'orderby'        => 'meta_value',              // 'meta_value', 'author', 'date', 'title', 'modified', 'parent', rand',
            'order'          => 'ASC',                    // 'ASC', 'DESC'
            'posts_per_page' => bbp_get_topics_per_page(), // Topics per page
            'paged'          => bbp_get_paged(),           // Page Number
            's'              => $default_topic_search,     // Topic Search
            'show_stickies'  => false,    // Ignore sticky topics?
            'max_num_pages'  => false,                     // Maximum number of pages to show
            'post__in'       => $allowed_topics
        );
    
        // What are the default allowed statuses (based on user caps)
        if ( bbp_get_view_all() ) {
    
            // Default view=all statuses
            $post_statuses = array(
                bbp_get_public_status_id(),
                bbp_get_closed_status_id(),
                bbp_get_spam_status_id(),
                bbp_get_trash_status_id()
            );
    
            // Add support for private status
            if ( current_user_can( 'read_private_topics' ) ) {
                $post_statuses[] = bbp_get_private_status_id();
            }
    
            // Join post statuses together
            $default['post_status'] = join( ',', $post_statuses );
    
        // Lean on the 'perm' query var value of 'readable' to provide statuses
        } else {
            $default['perm'] = 'readable';
        }
    
        // Maybe query for topic tags
        if ( bbp_is_topic_tag() ) {
            $default['term']     = bbp_get_topic_tag_slug();
            $default['taxonomy'] = bbp_get_topic_tag_tax_id();
        }
    
        /** Setup *****************************************************************/
    
        // Parse arguments against default values
        $r = bbp_parse_args( $args, $default, 'has_topics' );
    
        // Get bbPress
        $bbp = bbpress();
    
        // Call the query
        $bbp->topic_query = new WP_Query( $r );
    
        // Set post_parent back to 0 if originally set to 'any'
        if ( 'any' == $r['post_parent'] )
            $r['post_parent'] = 0;
    
        // Limited the number of pages shown
        if ( !empty( $r['max_num_pages'] ) )
            $bbp->topic_query->max_num_pages = $r['max_num_pages'];
    
        // If no limit to posts per page, set it to the current post_count
        if ( -1 == $r['posts_per_page'] )
            $r['posts_per_page'] = $bbp->topic_query->post_count;
    
        // Add pagination values to query object
        $bbp->topic_query->posts_per_page = $r['posts_per_page'];
        $bbp->topic_query->paged          = $r['paged'];
    
        // Only add pagination if query returned results
        if ( ( (int) $bbp->topic_query->post_count || (int) $bbp->topic_query->found_posts ) && (int) $bbp->topic_query->posts_per_page ) {
    
            // Limit the number of topics shown based on maximum allowed pages
            if ( ( !empty( $r['max_num_pages'] ) ) && $bbp->topic_query->found_posts > $bbp->topic_query->max_num_pages * $bbp->topic_query->post_count )
                $bbp->topic_query->found_posts = $bbp->topic_query->max_num_pages * $bbp->topic_query->post_count;
    
            // If pretty permalinks are enabled, make our pagination pretty
            if ( $wp_rewrite->using_permalinks() ) {
    
                // User's topics
                if ( bbp_is_single_user_topics() ) {
                    $base = bbp_get_user_topics_created_url( bbp_get_displayed_user_id() );
    
                // User's favorites
                } elseif ( bbp_is_favorites() ) {
                    $base = bbp_get_favorites_permalink( bbp_get_displayed_user_id() );
    
                // User's subscriptions
                } elseif ( bbp_is_subscriptions() ) {
                    $base = bbp_get_subscriptions_permalink( bbp_get_displayed_user_id() );
    
                // Root profile page
                } elseif ( bbp_is_single_user() ) {
                    $base = bbp_get_user_profile_url( bbp_get_displayed_user_id() );
    
                // View
                } elseif ( bbp_is_single_view() ) {
                    $base = bbp_get_view_url();
    
                // Topic tag
                } elseif ( bbp_is_topic_tag() ) {
                    $base = bbp_get_topic_tag_link();
    
                // Page or single post
                } elseif ( is_page() || is_single() ) {
                    $base = get_permalink();
    
                // Topic archive
                } elseif ( bbp_is_topic_archive() ) {
                    $base = bbp_get_topics_url();
    
                // Default
                } else {
                    $base = get_permalink( (int) $r['post_parent'] );
                }
    
                // Use pagination base
                $base = trailingslashit( $base ) . user_trailingslashit( $wp_rewrite->pagination_base . '/%#%/' );
    
            // Unpretty pagination
            } else {
                $base = add_query_arg( 'paged', '%#%' );
            }
    
            // Pagination settings with filter
            $bbp_topic_pagination = apply_filters( 'bbp_topic_pagination', array (
                'base'      => $base,
                'format'    => '',
                'total'     => $r['posts_per_page'] == $bbp->topic_query->found_posts ? 1 : ceil( (int) $bbp->topic_query->found_posts / (int) $r['posts_per_page'] ),
                'current'   => (int) $bbp->topic_query->paged,
                'prev_text' => is_rtl() ? '→' : '←',
                'next_text' => is_rtl() ? '←' : '→',
                'mid_size'  => 1
            ) );
    
            // Add pagination to query object
            $bbp->topic_query->pagination_links = paginate_links( $bbp_topic_pagination );
    
            // Remove first page from pagination
            $bbp->topic_query->pagination_links = str_replace( $wp_rewrite->pagination_base . "/1/'", "'", $bbp->topic_query->pagination_links );
        }
    
        // Return object
        return apply_filters( 'tehnik_bpp_filter_topics_by_permissions', $bbp->topic_query->have_posts(), $bbp->topic_query );
    }
    
    //add_filter('bbp_has_topics', 'tehnik_bpp_filter_topics_by_permissions', 10, 2 );
    Thread Starter Aleksandar Adamovic

    (@ezakiel)

    Sorry for late reply, I get to work on this only during my free time.

    Thanks for pointing me to that file. I looked at it so many times and missed that code every time. I think I have it working now. I will be releasing an update once I clean things up a bit.

    I tested the commenting system on my site and it is working fine for me. Did you get any errors?

    Here is the code I used. I could not encounter any issues, but then again my test forums are somewhat small.

    add_filter('bbp_has_topics', 'tehnik_bbp_has_topics', 1, 2);
    
    function tehnik_bbp_has_topics($args = '') {
        global $wp_rewrite;
    
        /** Defaults ************************************************************* */
        // Other defaults
        $default_topic_search = !empty($_REQUEST['ts']) ? $_REQUEST['ts'] : false;
        $default_show_stickies = (bool) ( bbp_is_single_forum() || bbp_is_topic_archive() ) && ( false === $default_topic_search );
        $default_post_parent = bbp_is_single_forum() ? bbp_get_forum_id() : 'any';
    
        // Default argument array
        $default = array(
            'post_type' => bbp_get_topic_post_type(), // Narrow query down to bbPress topics
            'post_parent' => $default_post_parent, // Forum ID
            'meta_key' => '_bbp_last_active_time', // Make sure topic has some last activity time
            'orderby' => 'meta_value', // 'meta_value', 'author', 'date', 'title', 'modified', 'parent', rand',
            'order' => 'DESC', // 'ASC', 'DESC'
            'posts_per_page' => bbp_get_topics_per_page(), // Topics per page
            'paged' => bbp_get_paged(), // Page Number
            's' => $default_topic_search, // Topic Search
            'show_stickies' => $default_show_stickies, // Ignore sticky topics?
            'max_num_pages' => false, // Maximum number of pages to show
        );
    
        //Get an array of IDs which the current user has permissions to view
        $allowed_forums = tehnik_bpp_get_permitted_post_ids(new WP_Query($default));
    
        // The default forum query with allowed forum ids array added
        $default['post__in'] = $allowed_forums;
    
        // What are the default allowed statuses (based on user caps)
        if (bbp_get_view_all()) {
    
            // Default view=all statuses
            $post_statuses = array(
                bbp_get_public_status_id(),
                bbp_get_closed_status_id(),
                bbp_get_spam_status_id(),
                bbp_get_trash_status_id()
            );
    
            // Add support for private status
            if (current_user_can('read_private_topics')) {
                $post_statuses[] = bbp_get_private_status_id();
            }
    
            // Join post statuses together
            $default['post_status'] = join(',', $post_statuses);
    
            // Lean on the 'perm' query var value of 'readable' to provide statuses
        } else {
            $default['perm'] = 'readable';
        }
    
        // Maybe query for topic tags
        if (bbp_is_topic_tag()) {
            $default['term'] = bbp_get_topic_tag_slug();
            $default['taxonomy'] = bbp_get_topic_tag_tax_id();
        }
    
        /** Setup **************************************************************** */
        // Parse arguments against default values
        $r = bbp_parse_args($args, $default, 'has_topics');
    
        // Get bbPress
        $bbp = bbpress();
    
        // Call the query
        $bbp->topic_query = new WP_Query($r);
    
        // Set post_parent back to 0 if originally set to 'any'
        if ('any' == $r['post_parent'])
            $r['post_parent'] = 0;
    
        // Limited the number of pages shown
        if (!empty($r['max_num_pages']))
            $bbp->topic_query->max_num_pages = $r['max_num_pages'];
    
        /** Stickies ************************************************************* */
        // Put sticky posts at the top of the posts array
        if (!empty($r['show_stickies']) && $r['paged'] <= 1) {
    
            // Get super stickies and stickies in this forum
            $stickies = bbp_get_super_stickies();
    
            // Get stickies for current forum
            if (!empty($r['post_parent'])) {
                $stickies = array_merge($stickies, bbp_get_stickies($r['post_parent']));
            }
    
            // Remove any duplicate stickies
            $stickies = array_unique($stickies);
    
            // We have stickies
            if (is_array($stickies) && !empty($stickies)) {
    
                // Start the offset at -1 so first sticky is at correct 0 offset
                $sticky_offset = -1;
    
                // Loop over topics and relocate stickies to the front.
                foreach ($stickies as $sticky_index => $sticky_ID) {
    
                    // Get the post offset from the posts array
                    $post_offsets = wp_filter_object_list($bbp->topic_query->posts, array('ID' => $sticky_ID), 'OR', 'ID');
    
                    // Continue if no post offsets
                    if (empty($post_offsets)) {
                        continue;
                    }
    
                    // Loop over posts in current query and splice them into position
                    foreach (array_keys($post_offsets) as $post_offset) {
                        $sticky_offset++;
    
                        $sticky = $bbp->topic_query->posts[$post_offset];
    
                        // Remove sticky from current position
                        array_splice($bbp->topic_query->posts, $post_offset, 1);
    
                        // Move to front, after other stickies
                        array_splice($bbp->topic_query->posts, $sticky_offset, 0, array($sticky));
    
                        // Cleanup
                        unset($stickies[$sticky_index]);
                        unset($sticky);
                    }
    
                    // Cleanup
                    unset($post_offsets);
                }
    
                // Cleanup
                unset($sticky_offset);
    
                // If any posts have been excluded specifically, Ignore those that are sticky.
                if (!empty($stickies) && !empty($r['post__not_in'])) {
                    $stickies = array_diff($stickies, $r['post__not_in']);
                }
    
                // Fetch sticky posts that weren't in the query results
                if (!empty($stickies)) {
    
                    // Query to use in get_posts to get sticky posts
                    $sticky_query = array(
                        'post_type' => bbp_get_topic_post_type(),
                        'post_parent' => 'any',
                        'meta_key' => '_bbp_last_active_time',
                        'orderby' => 'meta_value',
                        'order' => 'DESC',
                        'include' => $stickies
                    );
    
                    //Get an array of IDs which the current user has permissions to view
                    $allowed_forums = tehnik_bpp_get_permitted_post_ids(new WP_Query($sticky_query));
    
                    // The default forum query with allowed forum ids array added
                    $sticky_query['post__in'] = $allowed_forums;
    
                    // Cleanup
                    unset($stickies);
    
                    // What are the default allowed statuses (based on user caps)
                    if (bbp_get_view_all()) {
                        $sticky_query['post_status'] = $r['post_status'];
    
                        // Lean on the 'perm' query var value of 'readable' to provide statuses
                    } else {
                        $sticky_query['post_status'] = $r['perm'];
                    }
    
                    // Get all stickies
                    $sticky_posts = get_posts($sticky_query);
                    if (!empty($sticky_posts)) {
    
                        // Get a count of the visible stickies
                        $sticky_count = count($sticky_posts);
    
                        // Merge the stickies topics with the query topics .
                        $bbp->topic_query->posts = array_merge($sticky_posts, $bbp->topic_query->posts);
    
                        // Adjust loop and counts for new sticky positions
                        $bbp->topic_query->found_posts = (int) $bbp->topic_query->found_posts + (int) $sticky_count;
                        $bbp->topic_query->post_count = (int) $bbp->topic_query->post_count + (int) $sticky_count;
    
                        // Cleanup
                        unset($sticky_posts);
                    }
                }
            }
        }
    
        // If no limit to posts per page, set it to the current post_count
        if (-1 == $r['posts_per_page'])
            $r['posts_per_page'] = $bbp->topic_query->post_count;
    
        // Add pagination values to query object
        $bbp->topic_query->posts_per_page = $r['posts_per_page'];
        $bbp->topic_query->paged = $r['paged'];
    
        // Only add pagination if query returned results
        if (( (int) $bbp->topic_query->post_count || (int) $bbp->topic_query->found_posts ) && (int) $bbp->topic_query->posts_per_page) {
    
            // Limit the number of topics shown based on maximum allowed pages
            if ((!empty($r['max_num_pages']) ) && $bbp->topic_query->found_posts > $bbp->topic_query->max_num_pages * $bbp->topic_query->post_count)
                $bbp->topic_query->found_posts = $bbp->topic_query->max_num_pages * $bbp->topic_query->post_count;
    
            // If pretty permalinks are enabled, make our pagination pretty
            if ($wp_rewrite->using_permalinks()) {
    
                // User's topics
                if (bbp_is_single_user_topics()) {
                    $base = bbp_get_user_topics_created_url(bbp_get_displayed_user_id());
    
                    // User's favorites
                } elseif (bbp_is_favorites()) {
                    $base = bbp_get_favorites_permalink(bbp_get_displayed_user_id());
    
                    // User's subscriptions
                } elseif (bbp_is_subscriptions()) {
                    $base = bbp_get_subscriptions_permalink(bbp_get_displayed_user_id());
    
                    // Root profile page
                } elseif (bbp_is_single_user()) {
                    $base = bbp_get_user_profile_url(bbp_get_displayed_user_id());
    
                    // View
                } elseif (bbp_is_single_view()) {
                    $base = bbp_get_view_url();
    
                    // Topic tag
                } elseif (bbp_is_topic_tag()) {
                    $base = bbp_get_topic_tag_link();
    
                    // Page or single post
                } elseif (is_page() || is_single()) {
                    $base = get_permalink();
    
                    // Topic archive
                } elseif (bbp_is_topic_archive()) {
                    $base = bbp_get_topics_url();
    
                    // Default
                } else {
                    $base = get_permalink((int) $r['post_parent']);
                }
    
                // Use pagination base
                $base = trailingslashit($base) . user_trailingslashit($wp_rewrite->pagination_base . '/%#%/');
    
                // Unpretty pagination
            } else {
                $base = add_query_arg('paged', '%#%');
            }
    
            // Pagination settings with filter
            $bbp_topic_pagination = apply_filters('bbp_topic_pagination', array(
                'base' => $base,
                'format' => '',
                'total' => $r['posts_per_page'] == $bbp->topic_query->found_posts ? 1 : ceil((int) $bbp->topic_query->found_posts / (int) $r['posts_per_page']),
                'current' => (int) $bbp->topic_query->paged,
                'prev_text' => is_rtl() ? '&rarr;' : '&larr;',
                'next_text' => is_rtl() ? '&larr;' : '&rarr;',
                'mid_size' => 1
                    ));
    
            // Add pagination to query object
            $bbp->topic_query->pagination_links = paginate_links($bbp_topic_pagination);
    
            // Remove first page from pagination
            $bbp->topic_query->pagination_links = str_replace($wp_rewrite->pagination_base . "/1/'", "'", $bbp->topic_query->pagination_links);
        }
    
        // Return object
        return  array($bbp->topic_query->have_posts(), $bbp->topic_query);
    }

    thanks again alex

    commenting on your site works fine for me, but only allows login via twitter or openID, FB & G+ login buttons are apparently not configured

    sam

    I’ll chime in here. This is badly needed functionality. I’m sure it is worth listing in the repository. As soon as word gets out in bbpress, there will be plenty of takers I’m sure.

    Thanks Aleks.

Viewing 12 replies - 1 through 12 (of 12 total)
  • The topic ‘Members and bbPress’ is closed to new replies.