Useful Functions and Hacks When Using S2member w/ BuddyPress
Hey there guys, i’m working on a website where i’m integrating s2member functionality with buddypress. I thought some of the things I’ve come across may be useful to other people.
1. Filter Users Displayed in Members Directory by s2member role.
In your plugins/buddypress/bp-templates/bp-legacy/buddypress/members/ folder edit the file “members-loop.php”. Just under
at the top 20 lines of the file we need to write some PHP code to build a comma separated list of ID’s based on the s2member role or roles that we want. In my case I wanted only members of “s2member_level2″.
It is recommended to only ever edit a copy of template file that you have copied over to your theme or child theme otherwise your changes will be overwritten on updates.
$args = array('role' => 's2member_level2', 'fields' => array('id')); // The User Query $user_query = new WP_User_Query( $args ); $custom_ids = ''; for($i = 0;$i results); $i++){ $a = $user_query->results[$i]->id; $custom_ids .= $a.","; }
Now that we’ve made a comma separated string of ids ($custom_ids), we need to pass it to the members loop.
Change
if(bp_has_members( bp_ajax_querystring( 'members' ) ) ) :
to
if(bp_has_members('per_page=30&type=alphabetical&'.'include='.$custom_ids ) ) :
In my case I wanted to make sure at most 30 members showed up, and that they were in alphabetical order.
Done.
2. Importing s2member custom fields to buddypress fields
You may be asking; why??? Well, it turns out that when you have the s2member option to integrate with buddypress it doesn’t actually import it’d data to the buddypress tables. It just binds it’s self to the ‘Base’ group, Which will show up by default in buddypress profiles. When it doesn’t import to the buddypress tables, it was very difficult for me to manipulate how the information showed up. Particularly the fact that I have the users give me their address information, and I don’t want that to even be an option to show in user profiles.
So instead of using s2member to integrate automatically, I wrote a function that would check a users information when they login. If they have certain information in s2member that is not in their BP Profile, it will add it automatically.
Option 1:
in functions.php add the code:
<?php add_action('wp_head','s2_profile_field_update',10,2); function s2_profile_field_update() { global $current_user; get_currentuserinfo(); if(current_user_is("s2member_level2")){ if(get_user_field("s2member_login_counter") < 1000){ if(xprofile_get_field_data('Nationality',$current_user->id) == '' && get_user_field('nationality') != '') { xprofile_set_field_data('Nationality', $current_user->id, get_user_field('nationality')); } if(xprofile_get_field_data('Age', $current_user->id) == '' && get_user_field('age') != '') { xprofile_set_field_data('Age', $current_user->id, get_user_field('age')); } if(xprofile_get_field_data('School', $current_user->id) == '' && get_user_field('school') != '') { xprofile_set_field_data('School', $current_user->id, get_user_field('school')); } } } } ?>
You can change Nationality to what ever the name is of the extended BP field (in users>profile fields).
And of course you can duplicate the if statements for how every many fields you want to import from s2memeber -> BP.
Also note that if(get_user_field("s2member_login_counter") < 1000)
mean’s that this process will run for any user that logs in with membership role s2member_level2 and has logged in less than 1000 times. I used 1000 times because I want any member at this moment who logs in to have their profiles populated. In the future I will drop it down to 1 or 2.
Alternatively we could use a for loop in order to make any later changes a bit simpler:
// Function to populate BP Profile Fields w/ S2member Fields. add_action('wp_head','s2_profile_field_update',10,2); function s2_profile_field_update() { global $current_user; //Array of xprofile field names $xprofile_fields = array('Nationality','Age','School'); //Array of s2member field slugs $s2member_fields = array('nationality','age','school'); get_currentuserinfo(); if( current_user_is("s2member_level2") ) { if(get_user_field("s2member_login_counter") < 1000) { for($i = 0; $i < sizeof($xprofile_fields); $i++) { if(xprofile_get_field_data($xprofile_fields[i], $current_user->id) == '' && get_user_field($s2member_fields[i]) != '' ) { xprofile_set_field_data($xprofile_fields[i], $current_user->id, get_user_field($s2member_fields[i]) ); } } } } }
Option 2: Suggested by @shanebp
Instead of checking for login count, and binding the function to ‘wp_head’ which will run on every page load, it would be more resource efficient to bind the function to the ‘wp_login’ action which will run once; when the user logs into the site. If you want to get really technical – which the computer engineer in me always does – you could argue that the process has been reduced from a time complexity of O(n)
to O(n/n) = O(1)
where n = the # of page loads from the user. A simple but substantial modification. Rock On @shanebp!
add_action('wp_login','s2_profile_field_update',10,2); function s2_profile_field_update() { global $current_user; get_currentuserinfo(); if( current_user_is("s2member_level2") ) { if(xprofile_get_field_data('Nationality',$current_user->id) == '' && get_user_field('nationality') != '') { xprofile_set_field_data('Nationality', $current_user->id, get_user_field('nationality')); } } }
I’ll post more as I gather it. But in the mean time I hope this helps some people.
\M