The problem is, in essence, this: You are filtering for member type/role at the template level, *after* the query has already taken place. So: you run bp_has_members()
. It returns 10 users that match the current params, which include the current page, the per_page number, and the dropdown filter (last active, alphabetical, etc). Then, inside of your template loop, you are only displaying a subset of those ten returned members – ie, those that match your s2member role.
In order to make a custom directory *and* have your pagination work, you’ll need to modify the query *before* it happens. One relatively simple way to do this is to pass an include
parameter to bp_has_members()
, which would limit the query to users that meet your s2member criteria.
Because we’re talking about custom user roles as assigned by s2member (and because user roles are stored in a way by WP that doesn’t allow this kind of query to be very efficient), this is going to be pretty tricky. This is totally untested, and probably not very fast at very large scale, but you could try something like the following:
<?php
global $wpdb;
$level3_user_ids = $wpdb->get_col( "SELECT user_id FROM {$wpdb->usermeta} WHERE meta_key = 'wp_capabilities' AND meta_value LIKE '%s2member_level3%'" );
$level3_user_ids_param = implode( ',', $level3_user_ids );
if ( bp_has_members( bp_ajax_querystring( 'members' ) . '&page_arg=bapage&per_page=10&include=' . $level3_user_ids_param ) ) : ?>
Then you will *not* need to do the level3 check inside the loop, because the 10 items returned will already be limited properly.
Like I said, this is off the top of my head and may not work without further modification. You may have to do some more experimentation to get an accurate whitelist of user ids for each directory type. But, no matter how you do it, the above example should show you a good technique for limiting the bp_has_members()
query to a subset of all users (which is the BuddyPress-related part of this puzzle – the other problem is related to s2member).