New in version 0.9.80
The Groups module provides a comprehensive API for managing cohorts, teams, and group-based access. This guide covers the public API functions, hooks, and filters available for extending the Groups functionality.
Checking Module Status
Before using Groups APIs, verify the module is active:
use BaselMedia\BricksMembers\Core\ModuleRegistry;
if ( ModuleRegistry::is_active( 'groups' ) ) {
// Groups functionality available
}
Helper Functions
GroupsHelperService::get_instance()->get_user_active_group_for_post()
Get the user’s active group ID for a specific post context.
/**
* @param int $user_id User ID
* @param int $post_id Post ID
* @return int|null Group ID or null if no active group
*/
$group_id = \BaselMedia\BricksMembers\Modules\Groups\GroupsHelperService::get_instance()
->get_user_active_group_for_post( $user_id, $post_id );
brm_get_group()
Retrieve group data by ID.
/**
* @param int $group_id Group ID
* @return array|null Group data or null if not found
*/
$group = brm_get_group( $group_id );
// Returns array with keys:
// id, name, owner_user_id, group_type, total_seats, used_seats,
// reserved_seats, grantable_levels, default_levels, status, starts_at, expires_at,
// invite_guest_redirect_page_id, invite_post_claim_redirect_page_id
brm_get_user_groups()
Get all groups a user belongs to.
/**
* @param int $user_id User ID
* @param array $args Optional: status, role filters
* @return array Array of group arrays
*/
$groups = brm_get_user_groups( $user_id, array( 'status' => 'active' ) );
brm_is_group_member()
Check if a user is a member of a group.
/**
* @param int $group_id Group ID
* @param int $user_id User ID
* @return bool
*/
$is_member = brm_is_group_member( $group_id, $user_id );
brm_get_user_group_role()
Get a user’s role within a group.
/**
* @param int $group_id Group ID
* @param int $user_id User ID
* @return string|null 'member', 'leader', or null if not a member
*/
$role = brm_get_user_group_role( $group_id, $user_id );
brm_group_grants_access_to_post()
Check if group membership grants access to a post.
/**
* @param int $group_id Group ID
* @param int $post_id Post ID
* @return bool
*/
$has_access = brm_group_grants_access_to_post( $group_id, $post_id );
GroupService Class
For more complex operations, use the GroupService singleton:
use BaselMedia\BricksMembers\Modules\Groups\GroupService;
$service = GroupService::get_instance();
Creating Groups
$group_id = $service->create_group( array(
'name' => 'Spring 2026 Cohort',
'owner_user_id' => get_current_user_id(),
'group_type' => 'cohort',
'total_seats' => 25,
'default_levels' => array( 1, 2 ),
'starts_at' => '2026-04-01 00:00:00',
'expires_at' => '2026-07-01 00:00:00',
) );
if ( is_wp_error( $group_id ) ) {
// Handle error
}
Updating Groups
$result = $service->update_group( $group_id, array(
'name' => 'Updated Name',
'total_seats' => 30,
) );
Archiving Groups
$service->archive_group( $group_id );
Member Management
// Add a member
$membership_id = $service->add_member( $group_id, $user_id, 'member' );
// Remove a member
$service->remove_member( $group_id, $user_id );
// Change role
$service->change_member_role( $group_id, $user_id, 'leader' );
// Transfer member to another group
$service->transfer_member( $user_id, $from_group_id, $to_group_id );
Getting Members
// Get all members
$members = $service->get_group_members( $group_id, array(
'status' => 'active',
'role' => 'member', // or 'leader'
) );
// Get a specific membership
$membership = $service->get_membership( $group_id, $user_id );
InvitationService Class
use BaselMedia\BricksMembers\Modules\Groups\InvitationService;
$invitation_service = InvitationService::get_instance();
Creating Invitations
// Email invitation (single-use, specific recipient)
$invitation_id = $invitation_service->create_email_invitation(
$group_id,
'student@example.com',
get_current_user_id(),
array(
'role' => 'member',
'expires_at' => '2026-04-01 00:00:00',
)
);
// Send the email
$invitation_service->send_invitation_email( $invitation_id );
// Join link (reusable, public)
$link_id = $invitation_service->create_join_link(
$group_id,
get_current_user_id(),
array(
'role' => 'member',
// For limited groups: must be <= current available seats.
// If omitted, defaults to available seats.
'max_uses' => 10,
'expires_at' => '2026-04-01 00:00:00',
)
);
// Get the shareable URL
$invitation = $invitation_service->get_invitation( $link_id );
$url = $invitation_service->get_claim_url( $invitation['token'] );
Validating and Claiming
// Validate before claiming
$validation = $invitation_service->validate_invitation( $token, $user_id );
if ( is_wp_error( $validation ) ) {
echo $validation->get_error_message();
return;
}
// Claim the invitation
$membership_id = $invitation_service->claim_invitation( $token, $user_id );
Managing Invitations
// Get by token
$invitation = $invitation_service->get_invitation_by_token( $token );
// Get all for a group
$invitations = $invitation_service->get_group_invitations( $group_id, array(
'status' => 'pending',
'type' => 'email', // or 'link'
) );
// Delete permanently
$invitation_service->delete_invitation( $invitation_id );
// Resend email
$invitation_service->send_invitation_email( $invitation_id );
SeatRuleService Class
For automated group creation from purchases:
use BaselMedia\BricksMembers\Modules\Groups\SeatRuleService;
$seat_service = SeatRuleService::get_instance();
// Create a rule
$rule_id = $seat_service->create_rule( array(
'product_ref' => 'team-license-pro',
'provider' => 'webhook',
'group_type' => 'team',
'levels_to_grant' => array( 1, 2 ),
'total_seats' => 5,
'create_mode' => 'per_purchase',
) );
// Process a purchase (creates group automatically)
$result = $seat_service->process_purchase(
'team-license-pro', // product_ref
'', // variation_ref
$owner_user_id, // who purchased
'order-123' // unique reference
);
// $result contains: group_id, membership_id, levels_granted
Member Chat Integration
When the Member Chat module is enabled, Groups becomes the lifecycle owner for primary group rooms.
brm_event_group_createdis used to create or resolve the primary group roombrm_event_group_member_addedsynchronizes the new user into the roombrm_event_group_member_removedremoves the user from the group’s chat roomsbrm_event_group_archivedarchives the group’s related chat rooms
The current primary-room contract is one room per group with scope = group and room_kind = primary_group in the Member Chat tables.
Actions (Hooks)
Group Lifecycle
// After group is created
add_action( 'brm_group_created', function( $group_id, $data ) {
// Send welcome email to owner, log analytics, etc.
}, 10, 2 );
// After group is updated
add_action( 'brm_group_updated', function( $group_id, $old_data, $new_data ) {
// Track changes
}, 10, 3 );
// After group is archived
add_action( 'brm_group_archived', function( $group_id, $reason ) {
// Cleanup, notifications
}, 10, 2 );
Member Lifecycle
// After member joins
add_action( 'brm_member_added', function( $group_id, $user_id, $role, $granted_levels ) {
// Welcome email, onboarding
}, 10, 4 );
// After member leaves/removed
add_action( 'brm_member_removed', function( $group_id, $user_id, $reason ) {
// Cleanup, notifications
}, 10, 3 );
// After role change
add_action( 'brm_member_role_changed', function( $group_id, $user_id, $old_role, $new_role ) {
// Update permissions, notify
}, 10, 4 );
Invitation Lifecycle
// After invitation created
add_action( 'brm_invitation_created', function( $invitation_id, $group_id, $email, $invited_by ) {
// Custom notifications, logging
}, 10, 4 );
// After invitation claimed
add_action( 'brm_invitation_claimed', function( $invitation_id, $user_id, $group_id, $invitation ) {
// Welcome sequence, analytics
}, 10, 4 );
// After invitation email sent
add_action( 'brm_invitation_email_sent', function( $invitation_id, $invitation ) {
// Track delivery
}, 10, 2 );
Filters
Customizing Invitation Emails
// Custom subject
add_filter( 'brm_invitation_email_subject', function( $subject, $invitation, $group ) {
return sprintf( 'Join %s - Exclusive Invitation', $group['name'] );
}, 10, 3 );
// Custom message body
add_filter( 'brm_invitation_email_message', function( $message, $invitation, $group, $claim_url ) {
return "You've been personally invited to join {$group['name']}.\n\n"
. "Click here to accept: {$claim_url}\n\n"
. "This is a limited opportunity!";
}, 10, 4 );
Customizing Claim Redirects
// After successful claim
add_filter( 'brm_invitation_claim_success_redirect', function( $url, $group_id, $user_id ) {
return home_url( '/welcome-to-group/?group=' . $group_id );
}, 10, 3 );
// After failed claim
add_filter( 'brm_invitation_claim_error_redirect', function( $url, $error, $token ) {
return home_url( '/invitation-error/?code=' . $error->get_error_code() );
}, 10, 3 );
Customizing Claim URL Base
add_filter( 'brm_invitation_claim_base_url', function( $url ) {
return home_url( '/join/' ); // Custom join page
} );
Bricks Integration
Custom Conditions
Register custom Bricks conditions based on groups:
add_filter( 'bricks/conditions/options', function( $options ) {
$options[] = array(
'key' => 'brm_custom_group_condition',
'label' => 'Custom Group Check',
'group' => 'brm',
'compare' => array(
'=' => 'equals',
'!=' => 'not equals',
),
'value' => array(
'type' => 'text',
'placeholder' => 'Group type',
),
);
return $options;
}, 15 );
add_filter( 'bricks/conditions/result', function( $result, $key, $condition ) {
if ( 'brm_custom_group_condition' !== $key ) {
return $result;
}
$group_id = \BaselMedia\BricksMembers\Modules\Groups\GroupsHelperService::get_instance()
->get_user_active_group_for_post( get_current_user_id(), get_the_ID() );
if ( ! $group_id ) {
return false;
}
$group = brm_get_group( $group_id );
$compare_value = $condition['value'] ?? '';
$compare = $condition['compare'] ?? '=';
$matches = $group['group_type'] === $compare_value;
return '=' === $compare ? $matches : ! $matches;
}, 10, 3 );
Custom Dynamic Tags
add_filter( 'bricks/dynamic_tags_list', function( $tags ) {
$tags[] = array(
'name' => '{brm_group:custom_field}',
'label' => 'Group Custom Field',
'group' => 'BricksMembers',
);
return $tags;
} );
add_filter( 'bricks/dynamic_data/render_tag', function( $value, $tag, $post, $context ) {
if ( strpos( $tag, '{brm_group:custom_field}' ) === false ) {
return $value;
}
$group_id = \BaselMedia\BricksMembers\Modules\Groups\GroupsHelperService::get_instance()
->get_user_active_group_for_post( get_current_user_id(), get_the_ID() );
if ( ! $group_id ) {
return '';
}
// Return your custom field value
return get_post_meta( $group_id, '_custom_group_field', true );
}, 10, 4 );
Database Schema
The Groups module uses four custom tables:
brm_groups
id– Primary keyname– Group nameowner_user_id– WordPress user ID of ownergroup_type– Type (cohort, team, etc.)total_seats,used_seats– Seat trackingreserved_seats– Pending email invite seat reservationsgrantable_levels,default_levels– JSON arraysinvite_guest_redirect_page_id,invite_post_claim_redirect_page_id– Optional redirect overridesstatus– active, archivedstarts_at,expires_at– Dates
brm_group_members
id– Primary keygroup_id– FK to brm_groupsuser_id– WordPress user IDrole– member, leadergranted_levels– JSON array of level IDsstatus– active, removed, transferredjoined_at,last_active_at– Timestamps
brm_seat_rules
id– Primary keyproduct_ref– Product identifierprovider– webhook, surecart, etc.group_type,total_seats– Group settingslevels_to_grant– JSON arraycreate_mode– per_purchase, shared
brm_group_invitations
id– Primary keygroup_id– FK to brm_groupstoken– Unique claim tokentype– email, linkemail– Recipient email (for email type)role– Role to assignmax_uses,use_count– Usage limitsstatus– pending, claimed, active, exhausted, expired, revoked
Best Practices
- Always check module status before using Groups APIs
- Use helper functions for simple lookups, services for complex operations
- Handle WP_Error returns from service methods
- Use filters to customize behavior rather than overriding
- Clear caches after direct database operations (use MutationContract)
Related Documentation
- Submissions API Reference — Groups integration for leader reviews
- Extending & Customizing — General extension patterns
- Extensions Registry & Events — React to group events
- Groups & Team Licenses (User Guide) — End-user documentation