Globals ************************************************
*/
// @deprecated.
if ( defined( 'BP_MEMBERS_SLUG' ) ) {
_doing_it_wrong( 'BP_MEMBERS_SLUG', esc_html__( 'Slug constants are deprecated.', 'buddypress' ), 'BuddyPress 12.0.0' );
$default_slug = BP_MEMBERS_SLUG;
}
// Fetch the default directory title.
$default_directory_titles = bp_core_get_directory_page_default_titles();
$default_directory_title = $default_directory_titles[$this->id];
// Override any passed args.
$args = array(
'slug' => $default_slug,
'root_slug' => isset( $bp->pages->members->slug ) ? $bp->pages->members->slug : $default_slug,
'has_directory' => true,
'rewrite_ids' => array(
'directory' => 'members',
'directory_type' => 'members_type',
'single_item' => 'member',
'single_item_component' => 'member_component',
'single_item_action' => 'member_action',
'single_item_action_variables' => 'member_action_variables',
'member_register' => 'register',
'member_activate' => 'activate',
'member_activate_key' => 'activate_key',
),
'directory_title' => isset( $bp->pages->members->title ) ? $bp->pages->members->title : $default_directory_title,
'search_string' => __( 'Search Members...', 'buddypress' ),
'global_tables' => array(
'table_name_invitations' => bp_core_get_table_prefix() . 'bp_invitations',
'table_name_last_activity' => bp_core_get_table_prefix() . 'bp_activity',
'table_name_optouts' => bp_core_get_table_prefix() . 'bp_optouts',
'table_name_signups' => $wpdb->base_prefix . 'signups', // Signups is a global WordPress table.
),
'notification_callback' => 'members_format_notifications',
'block_globals' => array(
'bp/dynamic-members' => array(
'widget_classnames' => array( 'widget_bp_core_members_widget', 'buddypress' ),
),
'bp/online-members' => array(
'widget_classnames' => array( 'widget_bp_core_whos_online_widget', 'buddypress' ),
),
'bp/active-members' => array(
'widget_classnames' => array( 'widget_bp_core_recently_active_widget', 'buddypress' ),
),
),
);
parent::setup_globals( $args );
// Additional globals.
$this->setup_additional_globals();
}
/**
* Set up canonical stack for this component.
*
* @since 2.1.0
*/
public function setup_canonical_stack() {
$bp = buddypress();
/** Default Profile Component ****************************************
*/
if ( bp_displayed_user_has_front_template() ) {
$bp->default_component = 'front';
} elseif ( bp_is_active( 'activity' ) && isset( $bp->pages->activity ) ) {
$bp->default_component = bp_get_activity_slug();
} else {
$bp->default_component = ( 'xprofile' === $bp->profile->id ) ? 'profile' : $bp->profile->id;
}
if ( defined( 'BP_DEFAULT_COMPONENT' ) && BP_DEFAULT_COMPONENT ) {
$default_component = BP_DEFAULT_COMPONENT;
if ( 'profile' === $default_component ) {
$default_component = 'xprofile';
}
if ( bp_is_active( $default_component ) ) {
$bp->default_component = BP_DEFAULT_COMPONENT;
}
}
/** Canonical Component Stack ****************************************
*/
if ( bp_displayed_user_id() ) {
$bp->canonical_stack['base_url'] = bp_displayed_user_url();
$action_variables = (array) bp_action_variables();
$path_chunks = bp_members_get_path_chunks(
array_merge(
array( bp_current_component(), bp_current_action() ),
array_filter( $action_variables )
)
);
if ( isset( $path_chunks['single_item_component'] ) ) {
$bp->canonical_stack['component'] = $path_chunks['single_item_component'];
// The canonical URL will not contain the default component.
if ( bp_is_current_component( $bp->default_component ) && ! bp_current_action() ) {
unset( $bp->canonical_stack['component'] );
} elseif ( isset( $path_chunks['single_item_action'] ) ) {
$bp->canonical_stack['action'] = $path_chunks['single_item_action'];
if ( isset( $path_chunks['single_item_action_variables'] ) ) {
$bp->canonical_stack['action_variables'] = $path_chunks['single_item_action_variables'];
}
}
// Looking at the single member root/home, so assume the default.
} else {
$bp->current_component = $bp->default_component;
}
/*
* If we're on a spammer's profile page, only users with the 'bp_moderate' cap
* can view subpages on the spammer's profile.
*
* users without the cap trying to access a spammer's subnav page will get
* redirected to the root of the spammer's profile page. this occurs by
* by removing the component in the canonical stack.
*/
if ( bp_is_user_spammer( bp_displayed_user_id() ) && ! bp_current_user_can( 'bp_moderate' ) ) {
unset( $bp->canonical_stack['component'] );
}
}
}
/**
* Get the Avatar and Cover image subnavs.
*
* @since 6.0.0
* @deprecated 12.0.0
*
* @return array The Avatar and Cover image subnavs.
*/
public function get_avatar_cover_image_subnavs() {
_deprecated_function( __METHOD__, '12.0.0' );
}
/**
* Register component navigation.
*
* @since 12.0.0
*
* @see `BP_Component::register_nav()` for a description of arguments.
*
* @param array $main_nav Optional. See `BP_Component::register_nav()` for
* description.
* @param array $sub_nav Optional. See `BP_Component::register_nav()` for
* description.
*/
public function register_nav( $main_nav = array(), $sub_nav = array() ) {
// Set slug to profile in case the xProfile component is not active
$slug = bp_get_profile_slug();
$main_nav = array(
'name' => _x( 'Profile', 'Member profile main navigation', 'buddypress' ),
'slug' => $slug,
'position' => 20,
'screen_function' => 'bp_members_screen_display_profile',
'default_subnav_slug' => 'public',
'item_css_id' => buddypress()->profile->id,
'generate' => ! bp_is_active( 'xprofile' ),
);
$sub_nav[] = array(
'name' => _x( 'View', 'Member profile view', 'buddypress' ),
'slug' => 'public',
'parent_slug' => $slug,
'screen_function' => 'bp_members_screen_display_profile',
'position' => 10,
'generate' => ! bp_is_active( 'xprofile' ),
);
$sub_nav[] = array(
'name' => _x( 'Change Profile Photo', 'Profile header sub menu', 'buddypress' ),
'slug' => 'change-avatar',
'parent_slug' => $slug,
'screen_function' => 'bp_members_screen_change_avatar',
'position' => 30,
'user_has_access' => false,
'user_has_access_callback' => 'bp_core_can_edit_settings',
'generate' => buddypress()->avatar->show_avatars,
);
$sub_nav[] = array(
'name' => _x( 'Change Cover Image', 'Profile header sub menu', 'buddypress' ),
'slug' => 'change-cover-image',
'parent_slug' => $slug,
'screen_function' => 'bp_members_screen_change_cover_image',
'position' => 40,
'user_has_access' => false,
'user_has_access_callback' => 'bp_core_can_edit_settings',
'generate' => bp_displayed_user_use_cover_image_header(),
);
parent::register_nav( $main_nav, $sub_nav );
}
/**
* Set up a profile nav in case the xProfile
* component is not active and a front template is
* used.
*
* @since 2.6.0
* @deprecated 12.0.0
*/
public function setup_profile_nav() {
_deprecated_function( __METHOD__, '12.0.0' );
}
/**
* Set up the xProfile nav.
*
* @since 6.0.0
* @deprecated 12.0.0
*/
public function setup_xprofile_nav() {
_deprecated_function( __METHOD__, '12.0.0' );
}
/**
* Get the Avatar and Cover image admin navs.
*
* @since 6.0.0
*
* @param string $admin_bar_menu_id The Admin bar menu ID to attach sub items to.
* @return array The Avatar and Cover image admin navs.
*/
public function get_avatar_cover_image_admin_navs( $admin_bar_menu_id = '' ) {
$wp_admin_nav = array();
$profile_slug = bp_get_profile_slug();
if ( ! $admin_bar_menu_id ) {
$admin_bar_menu_id = $this->id;
}
// Edit Avatar.
if ( buddypress()->avatar->show_avatars ) {
$wp_admin_nav[] = array(
'parent' => 'my-account-' . $admin_bar_menu_id,
'id' => 'my-account-' . $admin_bar_menu_id . '-change-avatar',
'title' => _x( 'Change Profile Photo', 'My Account Profile sub nav', 'buddypress' ),
'href' => bp_loggedin_user_url( bp_members_get_path_chunks( array( $profile_slug, 'change-avatar' ) ) ),
'position' => 30,
);
}
// Edit Cover Image
if ( bp_displayed_user_use_cover_image_header() ) {
$wp_admin_nav[] = array(
'parent' => 'my-account-' . $admin_bar_menu_id,
'id' => 'my-account-' . $admin_bar_menu_id . '-change-cover-image',
'title' => _x( 'Change Cover Image', 'My Account Profile sub nav', 'buddypress' ),
'href' => bp_loggedin_user_url( bp_members_get_path_chunks( array( $profile_slug, 'change-cover-image' ) ) ),
'position' => 40,
);
}
return $wp_admin_nav;
}
/**
* Set up the Admin Bar.
*
* @since 6.0.0
*
* @param array $wp_admin_nav Admin Bar items.
*/
public function setup_admin_bar( $wp_admin_nav = array() ) {
// Menus for logged in user.
if ( is_user_logged_in() ) {
$profile_slug = bp_get_profile_slug();
if ( ! bp_is_active( 'xprofile' ) ) {
// Add the "Profile" sub menu.
$wp_admin_nav[] = array(
'parent' => buddypress()->my_account_menu_id,
'id' => 'my-account-' . $this->id,
'title' => _x( 'Profile', 'My Account Profile', 'buddypress' ),
'href' => bp_loggedin_user_url( bp_members_get_path_chunks( array( $profile_slug ) ) ),
);
// View Profile.
$wp_admin_nav[] = array(
'parent' => 'my-account-' . $this->id,
'id' => 'my-account-' . $this->id . '-public',
'title' => _x( 'View', 'My Account Profile sub nav', 'buddypress' ),
'href' => bp_loggedin_user_url( bp_members_get_path_chunks( array( $profile_slug, 'public' ) ) ),
'position' => 10,
);
$wp_admin_nav = array_merge( $wp_admin_nav, $this->get_avatar_cover_image_admin_navs() );
/**
* The xProfile is active.
*
* Add the Change Avatar and Change Cover Image Admin Bar items
* to the xProfile Admin Bar Menu.
*/
} else {
add_filter( 'bp_xprofile_admin_nav', array( $this, 'setup_xprofile_admin_nav' ), 2 );
}
}
parent::setup_admin_bar( $wp_admin_nav );
}
/**
* Adds "Profile > Change Avatar" & "Profile > Change Cover Image" subnav item
* under the "Profile" adminbar menu.
*
* @since 6.0.0
*
* @param array $wp_admin_nav The Profile adminbar nav array.
* @return array
*/
public function setup_xprofile_admin_nav( $wp_admin_nav ) {
$items = $this->get_avatar_cover_image_admin_navs( buddypress()->profile->id );
if ( $items ) {
$wp_admin_nav = array_merge( $wp_admin_nav, $items );
}
return $wp_admin_nav;
}
/**
* Set up the title for pages and
.
*
* @since 1.5.0
*/
public function setup_title() {
$bp = buddypress();
if ( bp_is_my_profile() ) {
$bp->bp_options_title = __( 'You', 'buddypress' );
} elseif ( bp_is_user() ) {
$bp->bp_options_title = bp_get_displayed_user_fullname();
$bp->bp_options_avatar = bp_core_fetch_avatar( array(
'item_id' => bp_displayed_user_id(),
'type' => 'thumb',
/* translators: %s: member name */
'alt' => sprintf( __( 'Profile picture of %s', 'buddypress' ), $bp->bp_options_title )
) );
}
parent::setup_title();
}
/**
* Setup cache groups.
*
* @since 2.2.0
*/
public function setup_cache_groups() {
// Global groups.
wp_cache_add_global_groups( array(
'bp_last_activity',
'bp_member_member_type',
) );
parent::setup_cache_groups();
}
/**
* Adds the Members directory type, Registration and Activation rewrite tags.
*
* @since 12.0.0
*
* @param array $rewrite_tags Optional. See BP_Component::add_rewrite_tags() for
* description.
*/
public function add_rewrite_tags( $rewrite_tags = array() ) {
$rewrite_tags = array(
'directory_type' => '([^/]+)',
'member_register' => '([1]{1,})',
'member_activate' => '([1]{1,})',
'member_activate_key' => '([^/]+)',
);
parent::add_rewrite_tags( $rewrite_tags );
}
/**
* Adds the Registration and Activation rewrite rules.
*
* @since 12.0.0
*
* @param array $rewrite_rules Optional. See BP_Component::add_rewrite_rules() for
* description.
*/
public function add_rewrite_rules( $rewrite_rules = array() ) {
$rewrite_rules = array(
'directory_type' => array(
'regex' => $this->root_slug . '/' . bp_get_members_member_type_base() . '/([^/]+)/?$',
'order' => 50,
'query' => 'index.php?' . $this->rewrite_ids['directory'] . '=1&' . $this->rewrite_ids['directory_type'] . '=$matches[1]',
),
'member_activate' => array(
'regex' => bp_get_activate_slug() . '/?$',
'order' => 40,
'query' => 'index.php?' . $this->rewrite_ids['member_activate'] . '=1',
),
'member_activate_key' => array(
'regex' => bp_get_activate_slug() . '/([^/]+)/?$',
'order' => 30,
'query' => 'index.php?' . $this->rewrite_ids['member_activate'] . '=1&' . $this->rewrite_ids['member_activate_key'] . '=$matches[1]',
),
'member_register' => array(
'regex' => bp_get_signup_slug() . '/?$',
'order' => 20,
'query' => 'index.php?' . $this->rewrite_ids['member_register'] . '=1',
),
);
parent::add_rewrite_rules( $rewrite_rules );
}
/**
* Adds the Registration and Activation permastructs.
*
* @since 12.0.0
*
* @param array $permastructs Optional. See BP_Component::add_permastructs() for
* description.
*/
public function add_permastructs( $permastructs = array() ) {
$permastructs = array(
// Register permastruct.
$this->rewrite_ids['member_register'] => array(
'permastruct' => $this->register_permastruct,
'args' => array(),
),
// Activate permastruct.
$this->rewrite_ids['member_activate'] => array(
'permastruct' => $this->activate_permastruct,
'args' => array(),
),
);
parent::add_permastructs( $permastructs );
}
/**
* Parse the WP_Query and eventually display the component's directory or single item.
*
* @since 12.0.0
*
* @param WP_Query $query Required. See BP_Component::parse_query() for
* description.
*/
public function parse_query( $query ) {
/*
* If BP Rewrites are not in use, no need to parse BP URI globals another time.
* Legacy Parser should have already set these.
*/
if ( 'rewrites' !== bp_core_get_query_parser() ) {
return parent::parse_query( $query );
}
// Init the current member and member type.
$member = false;
$member_type = false;
$member_data = bp_rewrites_get_member_data();
if ( isset( $member_data['object'] ) && $member_data['object'] ) {
bp_reset_query( trailingslashit( $this->root_slug ) . $GLOBALS['wp']->request, $query );
$member = $member_data['object'];
// Make sure the Member's screen is fired.
add_action( 'bp_screens', 'bp_members_screen_display_profile', 3 );
}
if ( bp_is_site_home() && bp_is_directory_homepage( $this->id ) ) {
$query->set( $this->rewrite_ids['directory'], 1 );
}
// Which component are we displaying?
$is_members_component = 1 === (int) $query->get( $this->rewrite_ids['directory'] );
$is_register_component = 1 === (int) $query->get( $this->rewrite_ids['member_register'] );
$is_activate_component = 1 === (int) $query->get( $this->rewrite_ids['member_activate'] );
// Get BuddyPress main instance.
$bp = buddypress();
if ( $is_members_component ) {
$bp->current_component = 'members';
$member_slug = $query->get( $this->rewrite_ids['single_item'] );
$member_type_slug = $query->get( $this->rewrite_ids['directory_type'] );
if ( $member_slug ) {
/**
* Filter the portion of the URI that is the displayed user's slug.
*
* Eg. example.com/ADMIN (when root profiles is enabled)
* example.com/members/ADMIN (when root profiles isn't enabled)
*
* ADMIN would be the displayed user's slug.
*
* @since 2.6.0
*
* @param string $member_slug
*/
$member_slug = apply_filters( 'bp_core_set_uri_globals_member_slug', $member_slug );
$bp->current_component = '';
// Unless root profiles are on, the member shouldn't be set yet.
if ( ! $member ) {
$member = get_user_by( $member_data['field'], $member_slug );
if ( ! $member ) {
bp_do_404();
return;
}
}
// If the member is marked as a spammer, 404 (unless logged-in user is a super admin).
if ( bp_is_user_spammer( $member->ID ) ) {
if ( bp_current_user_can( 'bp_moderate' ) ) {
bp_core_add_message( __( 'This user has been marked as a spammer. Only site admins can view this profile.', 'buddypress' ), 'warning' );
} else {
bp_do_404();
return;
}
}
// Set the displayed user and the current item.
$bp->displayed_user->id = $member->ID;
$bp->current_item = $member_slug;
// The core userdata of the user who is currently being displayed.
if ( ! isset( $bp->displayed_user->userdata ) || ! $bp->displayed_user->userdata ) {
$bp->displayed_user->userdata = bp_core_get_core_userdata( bp_displayed_user_id() );
}
// Fetch the full name displayed user.
if ( ! isset( $bp->displayed_user->fullname ) || ! $bp->displayed_user->fullname ) {
$bp->displayed_user->fullname = '';
if ( isset( $bp->displayed_user->userdata->display_name ) ) {
$bp->displayed_user->fullname = $bp->displayed_user->userdata->display_name;
}
}
// The domain for the user currently being displayed.
if ( ! isset( $bp->displayed_user->domain ) || ! $bp->displayed_user->domain ) {
$bp->displayed_user->domain = bp_members_get_user_url( bp_displayed_user_id() );
}
// If a user is displayed, check if there is a front template and reset navigation.
if ( bp_get_displayed_user() ) {
$bp->displayed_user->front_template = bp_displayed_user_get_front_template();
// Reset the nav for the members component.
$this->nav = new BP_Core_Nav();
}
$member_component = $query->get( $this->rewrite_ids['single_item_component'] );
if ( $member_component ) {
// Check if the member's component slug has been customized.
$item_component_rewrite_id = bp_rewrites_get_custom_slug_rewrite_id( 'members', $member_component );
if ( $item_component_rewrite_id ) {
$member_component = str_replace( 'bp_member_', '', $item_component_rewrite_id );
}
$bp->current_component = $member_component;
}
$current_action = $query->get( $this->rewrite_ids['single_item_action'] );
if ( $current_action ) {
$context = sprintf( 'bp_member_%s_', $bp->current_component );
// Check if the member's component action slug has been customized.
$item_component_action_rewrite_id = bp_rewrites_get_custom_slug_rewrite_id( 'members', $current_action, $context );
if ( $item_component_action_rewrite_id ) {
$custom_action_slug = str_replace( $context, '', $item_component_action_rewrite_id );
// Make sure the action is stored as a slug: underscores need to be replaced by dashes.
$current_action = str_replace( '_', '-', $custom_action_slug );
}
$bp->current_action = $current_action;
}
$action_variables = $query->get( $this->rewrite_ids['single_item_action_variables'] );
if ( $action_variables ) {
$context = sprintf( 'bp_member_%1$s_%2$s_', $bp->current_component, $bp->current_action );
if ( ! is_array( $action_variables ) ) {
$action_variables = explode( '/', ltrim( $action_variables, '/' ) );
}
foreach ( $action_variables as $key_variable => $action_variable ) {
$item_component_action_variable_rewrite_id = bp_rewrites_get_custom_slug_rewrite_id( 'members', $action_variable, $context );
if ( $item_component_action_variable_rewrite_id ) {
$action_variables[ $key_variable ] = str_replace( $context, '', $item_component_action_variable_rewrite_id );
}
}
$bp->action_variables = $action_variables;
}
// Is this a member type query?
} elseif ( $member_type_slug ) {
$member_type = bp_get_member_types(
array(
'has_directory' => true,
'directory_slug' => $member_type_slug,
)
);
if ( $member_type ) {
$member_type = reset( $member_type );
$bp->current_member_type = $member_type;
} else {
$bp->current_component = '';
bp_do_404();
return;
}
}
// Set the BuddyPress queried object.
if ( isset( $bp->pages->members->id ) ) {
$query->queried_object = get_post( $bp->pages->members->id );
$query->queried_object_id = $query->queried_object->ID;
if ( $member ) {
$query->queried_object->single_item_name = $member->display_name;
} elseif ( $member_type ) {
$query->queried_object->directory_type_name = $member_type;
}
}
// Handle the custom registration page.
} elseif ( $is_register_component ) {
$bp->current_component = 'register';
// Handle the custom activation page.
} elseif ( $is_activate_component ) {
$bp->current_component = 'activate';
$current_action = $query->get( $this->rewrite_ids['member_activate_key'] );
if ( $current_action ) {
$bp->current_action = $current_action;
}
}
parent::parse_query( $query );
}
/**
* Check the parsed query is consistent with Members navigation.
*
* As the members’ component pages need a valid screen function to load the right BP Template,
* we need to make sure the current single item action exists inside the Members navigation and
* that the corresponding screen function is a valid callback.
*
* @since 12.0.0
*/
public function check_parsed_query() {
if ( bp_is_user() ) {
$single_item_component = bp_current_component();
$single_item_action = '';
if ( $single_item_component ) {
$single_item_action = bp_current_action();
}
// Viewing a single activity.
if ( 'activity' === $single_item_component && is_numeric( $single_item_action ) ) {
return;
}
$bp = buddypress();
if ( ! bp_is_active( $single_item_component ) && ! $bp->members->nav->get_primary( array( 'slug' => $single_item_component ), false ) ) {
bp_do_404();
return;
}
// Navigation is generated by a component.
if ( isset( $bp->{$single_item_component} ) ) {
$screen_function = '';
if ( isset( $bp->{$single_item_component}->sub_nav ) ) {
$screen_functions = wp_list_pluck( $bp->{$single_item_component}->sub_nav, 'screen_function', 'slug' );
if ( isset( $screen_functions[ $single_item_action ] ) ) {
$screen_function = $screen_functions[ $single_item_action ];
}
}
// Check if this nav item has been added from outside the Component's class.
if ( ! $screen_function ) {
$sub_nav = $this->nav->get( $single_item_component . '/' . $single_item_action );
if ( isset( $sub_nav->screen_function ) && $sub_nav->screen_function ) {
$screen_function = $sub_nav->screen_function;
}
}
if ( ! $single_item_action || ! $screen_function || ! is_callable( $screen_function ) ) {
bp_do_404();
return;
}
// Navigation is not generated by a component.
} else {
$sub_nav = $bp->members->nav->get_secondary(
array(
'parent_slug' => $single_item_component,
'slug' => $single_item_action,
),
false
);
if ( ! $sub_nav ) {
bp_do_404();
return;
}
}
}
}
/**
* Init the BP REST API.
*
* @since 5.0.0
* @since 6.0.0 Adds the Member Cover and Signup REST endpoints.
* @since 9.0.0 Moves the `BP_REST_Components_Endpoint` controller in `BP_Core` component.
*
* @param array $controllers Optional. See BP_Component::rest_api_init() for
* description.
*/
public function rest_api_init( $controllers = array() ) {
$controllers = array(
'BP_REST_Members_Endpoint',
'BP_REST_Attachments_Member_Avatar_Endpoint',
);
if ( bp_is_active( 'members', 'cover_image' ) ) {
$controllers[] = 'BP_REST_Attachments_Member_Cover_Endpoint';
}
if ( bp_get_signup_allowed() ) {
$controllers[] = 'BP_REST_Signup_Endpoint';
}
parent::rest_api_init( $controllers );
}
/**
* Register the BP Members Blocks.
*
* @since 6.0.0
* @since 12.0.0 Use the WP Blocks API v2.
*
* @param array $blocks Optional. See BP_Component::blocks_init() for
* description.
*/
public function blocks_init( $blocks = array() ) {
parent::blocks_init(
array(
'bp/member' => array(
'metadata' => trailingslashit( buddypress()->plugin_dir ) . 'bp-members/blocks/member',
'render_callback' => 'bp_members_render_member_block',
),
'bp/members' => array(
'metadata' => trailingslashit( buddypress()->plugin_dir ) . 'bp-members/blocks/members',
'render_callback' => 'bp_members_render_members_block',
),
'bp/dynamic-members' => array(
'metadata' => trailingslashit( buddypress()->plugin_dir ) . 'bp-members/blocks/dynamic-members',
'render_callback' => 'bp_members_render_dynamic_members_block',
),
'bp/online-members' => array(
'metadata' => trailingslashit( buddypress()->plugin_dir ) . 'bp-members/blocks/online-members',
'render_callback' => 'bp_members_render_online_members_block',
),
'bp/active-members' => array(
'metadata' => trailingslashit( buddypress()->plugin_dir ) . 'bp-members/blocks/active-members',
'render_callback' => 'bp_members_render_active_members_block',
),
)
);
}
}