BuddyPress: Sort members by current balance

Home / Tutorials / BuddyPress: Sort members by current balance

Note that this has not been tested with the latest version of BuddyPress

Description

In this tutorial I will show you how you can sort your BuddyPress members list according to your users current points balances.

All code snippets in this tutorial goes into your themes functions.php file.

Requirements

  • BuddyPress 1.5+
  • myCRED Installed and running

The setup

In order for us to sort users according to their balance, we will need to do two things:

  1. Insert the sorting order options into the drop-down menu on our members page.
  2. Adjust the BuddyPress user query to reflect our selected sorting option.

Adjusting the sorting drop-down menu

In the default BuddyPress theme, the drop-down menu that handles sorting on your members page is located in members/index.php and can be extended via the bp_members_directory_order_options action. So the first thing we are going to do is to hook into this action and insert our custom sorting options:

/**
 * Add Sort Members Option
 * @since 0.1
 * @version 1.0
 */
add_action( 'bp_members_directory_order_options', 'mycred_pro_add_sorting_options' );
function mycred_pro_add_sorting_options() { ?>
<option value="points-asc">Points Balance (Ascending)</option>
<option value="points-desc">Points Balance (Descending)</option>
<?php
}

The above example will insert two new options allowing us to sort users according to their current balance either in an Ascending order (0,1,2,3,4) or Descending order (10,9,8,7).

Adjust the BuddyPress User Query

Now that we have our custom options, we need to hook into BuddyPress and adjust the user query to reflect our selected options. To do this, we will use the bp_pre_user_query action which allows us to adjust the database query just before it is executed.

Incorrect SQL queries here will result in either an error message (if WP_DEBUG is enabled) or will return “No users found”.

/**
 * Adjust BP User Query
 * @since 0.1
 * @version 1.0
 */
add_action( 'bp_pre_user_query', 'mycred_pro_pre_user_query' );
function mycred_pro_pre_user_query( $BP_User_Query ) {
	// Only run this if one of our custom options is selected
	if ( in_array( $BP_User_Query->query_vars['type'], array( 'points-asc', 'points-desc' ) ) ) {
		global $wpdb;

		// Adjust SELECT
		$BP_User_Query->uid_clauses['select'] = "
SELECT DISTINCT u.{$BP_User_Query->uid_name} as id 
FROM {$wpdb->users} u 
INNER JOIN {$wpdb->usermeta} um 
	ON ( u.{$BP_User_Query->uid_name} = um.user_id )";

		// Adjust WHERE
		$BP_User_Query->uid_clauses['where'] = "WHERE um.meta_key = 'mycred_default'";

		// Adjust ORDER BY
		$BP_User_Query->uid_clauses['orderby'] = "ORDER BY um.meta_value+0";

		// Adjust ORDER
		$BP_User_Query->uid_clauses['order'] = ( $BP_User_Query->query_vars['type'] == 'points-asc' ) ? 'ASC' : 'DESC';
	}
}

For more information on how BuddyPress handles user searches, you can always check the bp-core-classes.php file which is located in plugins/buddypress/.

Done

That’s it! Save the above codes into your themes functions.php file and upload. If you have any questions or issues, feel free to post them below in the comments section.

  1. I love you Master G!!!

    This works like a charm and I think it should also be a standard feature for myCRED 1.4. Is there any way of making this the primary sorting method instead of the “Last Active” default or perhaps move these options to the top?

    1. Hey.

      I was thinking of adding it into 1.4 with some options but if you are looking to place this as the first option, you would need to do that via your BuddyPress theme by replacing the members/index.php file where the dropdown is located and move the options around.

      You could skip the first step in this tutorial and just insert the options directly in your theme file instead of using the action hook but if I am to insert this into 1.4, I would only be able to insert it as the last options (as shown in this tutorial).

  2. Thank you very much, I actually am using this to sort the buddypress member directory by distance from current user as well!

    Jaja, estoy usando el internet!

  3. Ah, actually the code is sort of messing with functionality for me a bit; hopefully you can help. I reverted my customized code back to your exact snippet and the problem persists.

    I have tabs that filter members based on an arbitrary field. So given, the user might be trying to sort by mycred balance (it’s actually a different field but for clarity sake we can just try and solve the problem for your code), they may also only be looking at members in the “Cat Group” filter. Essentially, I am filtering by passing a list of acceptable IDs (users who have the “Cat Group” attached to their profile). So to be concise:

    How can I get your query to only return results based on the currently acceptable, or included, user IDs?

    1. Okay, for anyone who stumbles across this – here is the solution

      simply append a list of IDs to the where statement. The exact code I used will be a little different, but heres the gist:

      $ids_to_include = explode("=", $scope);
      $ids_to_include = explode(",",$ids_to_include[1]);
      $ids_string = "";
      
      $id_count = 0;
      foreach($ids_to_include as $id){
      	if($id == ""){
      		continue;
      	}else{
      		if($id_count == 0)
      			$ids_string .= " AND (um.user_id = ".$id;
      		else
      			$ids_string .= " OR um.user_id = ".$id;		
      				
      		$id_count++;
      	}
      }
      if($ids_string != "")
      	$ids_string .= ")";	
      		
      $BP_User_Query->uid_clauses['where'] .= $ids_string;
      

      Where the initial input of $scope is formatted “include=[id1],[id2],[id3]

      The count variable is still a bit off based, but that was actually happening from Gabriel’s code so if I find a fix to that I’ll definitely post here (and here and on the buddypress forum topic im opening here: https://buddypress.org/support/topic/how-to-with-gabey-d-adding-location-filtering/ )

  4. Hello!
    Thank you for a great plugin!

    I have tried this snippet in order to sort members by they current balance. Paste the code in functions.php and by editing members loop by changing this code

    to this (order by points-desc by default)

    The problem is that after I did this the stopped working and also pagination at the end of the member list were gone.

    How could I fix this, because I would like to order members via they current points balance, but also have the search working.

    Thank you!

  5. Hello,

    Code in functions.php is exactly the same as you have provided. I just changed members loop sort desc by default.
    This line:

    I changed to this:

  6. Hi Gabriel, thanks you for this tip. Im starting to play with mycred and it’s fantastic! really a great work, thanks!

    I would like to contribui with a correction. when you want to list your friends sorted by balance it don’t work, it’s need to add a filter in the where clause for that. Here is how a did:

    // Adjust WHERE
    $BP_User_Query->uid_clauses['where'] = "WHERE um.meta_key = 'mycred_default'";
    
    // comprovamos que no sea un filtro de amistad
    if ($BP_User_Query->query_vars['user_id']) {
    	$fs = friends_get_friend_user_ids($BP_User_Query->query_vars['user_id']);
    	$fs = implode(',',$fs);
    	$BP_User_Query->uid_clauses['where'] .= " AND u.ID IN ($fs)";
    }
    
  7. Hi,
    i try to use this tutorial, but when i paste a code to function.php files i don’t see any changes.
    I use MyCred 1.6.1, WP 4.1.1, Buddypress 2.2.1 and SweetDate theme.

  8. What if you wanted to break it down by dates? So you would get a list of the users their point, but you wanted to calculate their point between 2 dates?

Leave a Reply

Last edited October 28, 2016