Skip to content

Instantly share code, notes, and snippets.

@vapvarun
Created October 30, 2025 07:44
Show Gist options
  • Select an option

  • Save vapvarun/86a928ae0e10d34e7907cc0df9fceff1 to your computer and use it in GitHub Desktop.

Select an option

Save vapvarun/86a928ae0e10d34e7907cc0df9fceff1 to your computer and use it in GitHub Desktop.
BuddyBoss Active/Inactive Members Filter - Based on LOGIN STATUS (never logged in vs logged in before)
<?php
/**
* BuddyBoss Theme Child Functions
* Active/Inactive Members Filter based on LOGIN STATUS
*
* @package BuddyBoss Theme Child
* @since 1.0.0
*/
// Exit if accessed directly
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* Enqueue parent and child theme styles
*/
add_action( 'wp_enqueue_scripts', 'buddyboss_theme_child_enqueue_styles', 999 );
function buddyboss_theme_child_enqueue_styles() {
wp_enqueue_style( 'parent-style', get_template_directory_uri() . '/style.css' );
wp_enqueue_style( 'child-style', get_stylesheet_directory_uri() . '/style.css', array( 'parent-style' ) );
}
/**
* Custom: Add "Active Members" and "Inactive Members" to member directory filter dropdown
*/
add_filter( 'bp_nouveau_get_members_filters', 'buddyboss_child_add_activity_filter_options', 10, 2 );
function buddyboss_child_add_activity_filter_options( $filters, $context ) {
// Only add to main members directory, not group members
if ( 'group' !== $context ) {
// Add our custom filter options to the existing dropdown
$filters['active_members'] = __( 'Active Members', 'buddyboss' );
$filters['inactive_members'] = __( 'Inactive Members', 'buddyboss' );
}
return $filters;
}
/**
* Custom: Filter members based on login status (Active = logged in before, Inactive = never logged in)
*/
add_filter( 'bp_after_has_members_parse_args', 'buddyboss_child_filter_members_by_activity' );
function buddyboss_child_filter_members_by_activity( $args ) {
// Only apply on members directory
if ( ! bp_is_members_directory() ) {
return $args;
}
// Check if one of our custom filter types is selected
if ( ! isset( $args['type'] ) || ! in_array( $args['type'], array( 'active_members', 'inactive_members' ) ) ) {
return $args;
}
global $wpdb;
// Get user IDs based on login status (last_activity meta)
if ( $args['type'] === 'active_members' ) {
// Get users who have last_activity (have logged in before)
$user_ids = $wpdb->get_col( "
SELECT DISTINCT user_id
FROM {$wpdb->usermeta}
WHERE meta_key = 'last_activity'
AND meta_value IS NOT NULL
AND meta_value != ''
" );
} else {
// Get users who have NO last_activity (never logged in)
$all_user_ids = $wpdb->get_col( "SELECT ID FROM {$wpdb->users}" );
$active_user_ids = $wpdb->get_col( "
SELECT DISTINCT user_id
FROM {$wpdb->usermeta}
WHERE meta_key = 'last_activity'
AND meta_value IS NOT NULL
AND meta_value != ''
" );
$user_ids = array_diff( $all_user_ids, $active_user_ids );
}
// Apply the filter
if ( ! empty( $user_ids ) ) {
$args['include'] = $user_ids;
} else {
// No users match the criteria, return empty result
$args['include'] = array( 0 );
}
return $args;
}
/**
* Custom: Add CSS for Active/Inactive member status badges
*/
add_action( 'wp_head', 'buddyboss_child_member_activity_status_styles' );
function buddyboss_child_member_activity_status_styles() {
if ( bp_is_members_directory() ) {
?>
<style>
.member-activity-status {
display: inline-block;
padding: 2px 8px;
border-radius: 3px;
font-size: 0.85em;
font-weight: 600;
}
.member-status-active {
background-color: #28a745;
color: #fff;
}
.member-status-inactive {
background-color: #6c757d;
color: #fff;
}
</style>
<?php
}
}

BuddyBoss Active/Inactive Members Filter - Installation Guide

This implementation adds "Active Members" and "Inactive Members" filter options to the BuddyBoss Members Directory based on LOGIN STATUS.

What It Does

  • Active Members: Shows members who have logged in at least once (have last_activity meta)
  • Inactive Members: Shows members who have NEVER logged in (no last_activity meta)
  • Visual Badges: (Optional) Displays Active/Inactive status badges on member cards

How It Works

The filter checks the last_activity user meta key:

  • When a user logs in to BuddyPress/BuddyBoss, the last_activity meta is set
  • Active = last_activity exists (user has logged in before)
  • Inactive = No last_activity (user has never logged in)

This is synchronized between:

  1. Filter dropdown logic (functions.php)
  2. Badge display (members-loop.php)

Installation Steps

Step 1: Add Functions (Required)

Copy the content of buddyboss-functions-complete.php to your child theme's functions.php file.

This includes:

  • Filter dropdown options
  • Filtering logic based on login status
  • CSS for status badges

Step 2: Add Template File (Optional - for visual badges)

If you want to show Active/Inactive badges on member cards:

  1. Create directory: wp-content/themes/buddyboss-theme-child/buddypress/members/
  2. Copy members-loop.php to this directory

Testing

  1. Go to your Members Directory (usually /members/)
  2. Look for the filter dropdown (top of the members list)
  3. You should see "Active Members" and "Inactive Members" options
  4. Select either option to filter the members list

Troubleshooting

Filters don't appear in dropdown:

  • Make sure BuddyPress is using the "Nouveau" template pack (BuddyBoss uses this by default)
  • Check that your child theme is activated
  • Clear any caching plugins

Filtering doesn't work:

  • Check if users have the last_activity user meta in your database
  • Verify the filter is being applied by checking the network tab in browser dev tools
  • Try disabling other plugins that might conflict

Badges don't show:

  • Make sure you copied the CSS section from functions.php
  • Verify the template file is in the correct location
  • Clear browser cache

Requirements

  • BuddyPress/BuddyBoss Platform
  • BuddyBoss Theme (with Nouveau template pack)
  • WordPress database access

Notes

  • This filter uses database queries on usermeta table
  • The last_activity meta is automatically set by BuddyPress when users log in
  • The filter works with AJAX (no page reload needed)
  • Both filter and badge use the same criteria for consistency
<?php
/**
* The template for members loop
*
* This template can be overridden by copying it to yourtheme/buddypress/members/members-loop.php.
*
* @since BuddyPress 3.0.0
* @version 1.0.0
*/
bp_nouveau_before_loop(); ?>
<?php
$footer_buttons_class = ( bp_is_active( 'friends' ) && bp_is_active( 'messages' ) ) ? ' footer-buttons-on' : '';
$is_follow_active = bp_is_active( 'activity' ) && function_exists( 'bp_is_activity_follow_active' ) && bp_is_activity_follow_active();
$follow_class = $is_follow_active ? ' follow-active' : '';
// Member directories elements.
$enabled_online_status = ! function_exists( 'bb_enabled_member_directory_element' ) || bb_enabled_member_directory_element( 'online-status' );
$enabled_profile_type = ! function_exists( 'bb_enabled_member_directory_element' ) || bb_enabled_member_directory_element( 'profile-type' );
$enabled_followers = ! function_exists( 'bb_enabled_member_directory_element' ) || bb_enabled_member_directory_element( 'followers' );
$enabled_last_active = ! function_exists( 'bb_enabled_member_directory_element' ) || bb_enabled_member_directory_element( 'last-active' );
$enabled_joined_date = ! function_exists( 'bb_enabled_member_directory_element' ) || bb_enabled_member_directory_element( 'joined-date' );
?>
<?php if ( bp_get_current_member_type() ) : ?>
<div class="bp-feedback info">
<span class="bp-icon" aria-hidden="true"></span>
<p><?php bp_current_member_type_message(); ?></p>
</div>
<?php endif; ?>
<?php if ( bp_has_members( bp_ajax_querystring( 'members' ) ) ) : ?>
<ul id="members-list" class="<?php bp_nouveau_loop_classes(); ?>">
<?php
while ( bp_members() ) :
bp_the_member();
$bp_get_member_user_id = bp_get_member_user_id();
$bp_get_member_permalink = bp_get_member_permalink();
// Check if members_list_item has content.
ob_start();
bp_nouveau_member_hook( '', 'members_list_item' );
$members_list_item_content = ob_get_clean();
$member_loop_has_content = ! empty( $members_list_item_content );
// Get member followers element.
$followers_count = '';
if ( $enabled_followers && function_exists( 'bb_get_followers_count' ) ) {
ob_start();
bb_get_followers_count( $bp_get_member_user_id );
$followers_count = ob_get_clean();
}
// Member joined data.
$member_joined_date = bb_get_member_joined_date( $bp_get_member_user_id );
// Member last activity.
$member_last_activity = bp_get_last_activity( $bp_get_member_user_id );
// Primary and secondary profile action buttons.
$profile_actions = bb_member_directories_get_profile_actions( $bp_get_member_user_id );
// Member switch button.
$member_switch_button = bp_get_add_switch_button( $bp_get_member_user_id );
$member_block_button = '';
$member_report_button = '';
if ( bp_is_active( 'moderation' ) && is_user_logged_in() ) {
// Member report button.
$report_button = bp_member_get_report_link(
array(
'button_element' => 'a',
'position' => 30,
'report_user' => true,
'parent_attr' => array(
'id' => 'user-report-' . $bp_get_member_user_id,
'class' => '',
),
'button_attr' => array(
'data-bp-content-id' => $bp_get_member_user_id,
'data-bp-content-type' => BP_Moderation_Members::$moderation_type_report,
'data-reported_type' => bp_moderation_get_report_type( BP_Moderation_Members::$moderation_type_report, $bp_get_member_user_id ),
),
)
);
$member_report_button = ! is_super_admin( $bp_get_member_user_id ) ? bp_get_button( $report_button ) : '';
// Member block button.
$block_button = bp_member_get_report_link(
array(
'button_element' => 'a',
'position' => 30,
'parent_attr' => array(
'id' => 'user-block-' . $bp_get_member_user_id,
'class' => '',
),
'button_attr' => array(
'data-bp-content-id' => $bp_get_member_user_id,
'data-bp-content-type' => BP_Moderation_Members::$moderation_type,
'data-reported_type' => bp_moderation_get_report_type( BP_Moderation_Members::$moderation_type, $bp_get_member_user_id ),
),
)
);
$member_block_button = ! is_super_admin( $bp_get_member_user_id ) ? bp_get_button( $block_button ) : '';
}
// Get Primary action.
$primary_action_btn = function_exists( 'bb_get_member_directory_primary_action' ) ? bb_get_member_directory_primary_action() : '';
?>
<li <?php bp_member_class( array( 'item-entry' ) ); ?> data-bp-item-id="<?php bp_member_user_id(); ?>" data-bp-item-component="members">
<div class="list-wrap
<?php
echo esc_attr( $footer_buttons_class ) .
esc_attr( $follow_class ) .
esc_attr( true === $member_loop_has_content ? ' has_hook_content' : '' ) .
esc_attr( ! empty( $profile_actions['secondary'] ) ? ' secondary-buttons' : ' no-secondary-buttons' ) .
esc_attr( ! empty( $primary_action_btn ) ? ' primary-button' : ' no-primary-buttons' );
?>
">
<div class="list-wrap-inner">
<div class="item-avatar">
<?php
$moderation_class = function_exists( 'bp_moderation_is_user_suspended' ) && bp_moderation_is_user_suspended( $bp_get_member_user_id ) ? 'bp-user-suspended' : '';
$moderation_class = function_exists( 'bp_moderation_is_user_blocked' ) && bp_moderation_is_user_blocked( $bp_get_member_user_id ) ? $moderation_class . ' bp-user-blocked' : $moderation_class;
?>
<a href="<?php echo esc_url( $bp_get_member_permalink ); ?>" class="<?php echo esc_attr( $moderation_class ); ?>">
<?php
if ( $enabled_online_status ) {
bb_user_presence_html( $bp_get_member_user_id );
}
bp_member_avatar( bp_nouveau_avatar_args() );
?>
</a>
</div>
<div class="item">
<div class="item-block">
<?php
$user_member_type = '';
if ( $enabled_profile_type && function_exists( 'bp_member_type_enable_disable' ) && true === bp_member_type_enable_disable() && true === bp_member_type_display_on_profile() ) {
$user_member_type = bp_get_user_member_type( $bp_get_member_user_id );
}
if ( ! empty( $user_member_type ) ) {
echo '<p class="item-meta member-type only-grid-view">' . wp_kses_post( $user_member_type ) . '</p>';
}
?>
<h2 class="list-title member-name">
<a href="<?php echo esc_url( $bp_get_member_permalink ); ?>"><?php bp_member_name(); ?></a>
</h2>
<?php
if ( ! empty( $user_member_type ) ) {
echo '<p class="item-meta member-type only-list-view">' . wp_kses_post( $user_member_type ) . '</p>';
}
// Custom: Check if user has logged in (Active/Inactive status based on last_activity)
$has_logged_in = bp_get_user_last_activity( $bp_get_member_user_id );
$activity_status = ! empty( $has_logged_in ) ? 'Active' : 'Inactive';
$activity_status_class = ! empty( $has_logged_in ) ? 'member-status-active' : 'member-status-inactive';
// Always show the meta line if we have any content to display
$show_meta_line = ( $enabled_last_active && $member_last_activity ) ||
( $enabled_joined_date && $member_joined_date ) ||
true; // Always show at least the status badge
if ( $show_meta_line ) :
echo '<p class="item-meta last-activity">';
$has_content = false;
// Show joined date if enabled and available
if ( $enabled_joined_date && $member_joined_date ) {
echo wp_kses_post( $member_joined_date );
$has_content = true;
}
// Show last activity if enabled and available
if ( $enabled_last_active && $member_last_activity ) {
if ( $has_content ) {
echo '<span class="separator">&bull;</span>';
}
echo wp_kses_post( $member_last_activity );
$has_content = true;
}
// Always add Active/Inactive label
if ( $has_content ) {
echo '<span class="separator">&bull;</span>';
}
echo '<span class="member-activity-status ' . esc_attr( $activity_status_class ) . '">' . esc_html( $activity_status ) . '</span>';
echo '</p>';
endif;
?>
</div>
<div class="flex align-items-center follow-container justify-center">
<?php echo wp_kses_post( $followers_count ); ?>
</div>
<?php if ( ! empty( $profile_actions['primary'] ) ) { ?>
<div class="flex only-grid-view align-items-center primary-action justify-center">
<?php echo wp_kses_post( $profile_actions['primary'] ); ?>
</div>
<?php } ?>
</div><!-- // .item -->
<div class="member-buttons-wrap">
<?php if ( ! empty( $profile_actions['secondary'] ) ) { ?>
<div class="flex only-grid-view button-wrap member-button-wrap footer-button-wrap">
<?php echo wp_kses_post( $profile_actions['secondary'] ); ?>
</div>
<?php
}
if ( ! empty( $profile_actions['primary'] ) ) {
?>
<div class="flex only-list-view align-items-center primary-action justify-center">
<?php echo wp_kses_post( $profile_actions['primary'] ); ?>
</div>
<?php } ?>
</div><!-- .member-buttons-wrap -->
</div>
<div class="bp-members-list-hook">
<?php if ( $member_loop_has_content ) { ?>
<a class="more-action-button" href="#" aria-label="<?php esc_attr_e( 'More options', 'buddyboss' ); ?>"><i class="bb-icon-menu-dots-h"></i></a>
<?php } ?>
<div class="bp-members-list-hook-inner">
<?php bp_nouveau_member_hook( '', 'members_list_item' ); ?>
</div>
</div>
<?php if ( ! empty( $member_switch_button ) || ! empty( $member_report_button ) || ! empty ( $member_block_button ) ) { ?>
<div class="bb_more_options member-dropdown">
<a href="#" class="bb_more_options_action bp-tooltip" data-bp-tooltip-pos="up" data-bp-tooltip="<?php esc_html_e( 'More Options', 'buddyboss' ); ?>" aria-label="<?php esc_html_e( 'More Options', 'buddyboss' ); ?>">
<i class="bb-icon-menu-dots-h"></i>
<span class="bp-screen-reader-text"><?php esc_html_e( 'More options', 'buddyboss' ); ?></span>
</a>
<div class="bb_more_options_list bb_more_dropdown">
<?php bp_get_template_part( 'common/more-options-view' ); ?>
<?php
echo wp_kses_post( $member_switch_button );
echo wp_kses_post( $member_report_button );
echo wp_kses_post( $member_block_button );
?>
</div>
<div class="bb_more_dropdown_overlay"></div>
</div><!-- .bb_more_options -->
<?php } ?>
</div>
</li>
<?php endwhile; ?>
</ul>
<?php
bp_nouveau_pagination( 'bottom' );
else :
bp_nouveau_user_feedback( 'members-loop-none' );
endif;
bp_nouveau_after_loop();
?>
<!-- Remove Connection confirmation popup -->
<div class="bb-remove-connection bb-action-popup" style="display: none">
<transition name="modal">
<div class="modal-mask bb-white bbm-model-wrap">
<div class="modal-wrapper">
<div class="modal-container">
<header class="bb-model-header">
<h4><span class="target_name"><?php echo esc_html__( 'Remove Connection', 'buddyboss' ); ?></span></h4>
<a class="bb-close-remove-connection bb-model-close-button" href="#">
<span class="bb-icon-l bb-icon-times"></span>
</a>
</header>
<div class="bb-remove-connection-content bb-action-popup-content">
<p>
<?php
echo sprintf(
/* translators: %s: The member name with HTML tags */
esc_html__( 'Are you sure you want to remove %s from your connections?', 'buddyboss' ),
'<span class="bb-user-name"></span>'
);
?>
</p>
</div>
<footer class="bb-model-footer flex align-items-center">
<a class="bb-close-remove-connection bb-close-action-popup" href="#"><?php echo esc_html__( 'Cancel', 'buddyboss' ); ?></a>
<a class="button push-right bb-confirm-remove-connection" href="#"><?php echo esc_html__( 'Confirm', 'buddyboss' ); ?></a>
</footer>
</div>
</div>
</div>
</transition>
</div> <!-- .bb-remove-connection -->
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment