Skip to content

Instantly share code, notes, and snippets.

@vapvarun
Created April 10, 2026 08:53
Show Gist options
  • Select an option

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

Select an option

Save vapvarun/ecf1caed630bd46350b707aaeffa3a02 to your computer and use it in GitHub Desktop.
Add Points, Badges and Leaderboards to BuddyPress with WP Gamification (bpcustomdev.com)
<?php
/**
* Register a custom point rule with WP Gamification.
*
* Hook: wp_gamification_register_rules
* Fires on 'init' after the plugin has loaded its core rule engine.
*/
add_action( 'wp_gamification_register_rules', function( $rule_registry ) {
$rule_registry->register( 'bp_profile_complete', [
'label' => __( 'BuddyPress Profile Completed', 'my-plugin' ),
'description' => __( 'Award points when a member fills all required profile fields.', 'my-plugin' ),
'points' => 25,
'once' => true, // Award only once per user.
'group' => 'community',
] );
} );
<?php
/**
* Trigger the custom point rule when all required BuddyPress
* profile fields are saved by a member.
*
* Hook: xprofile_updated_profile
*/
add_action( 'xprofile_updated_profile', function( $user_id ) {
// Check if every required field group has a value.
$required_fields = bp_xprofile_get_groups( [
'fetch_fields' => true,
'fetch_field_data' => true,
'user_id' => $user_id,
'hide_empty_fields' => false,
] );
$all_filled = true;
foreach ( $required_fields as $group ) {
foreach ( $group->fields as $field ) {
if ( $field->is_required && empty( $field->data->value ) ) {
$all_filled = false;
break 2;
}
}
}
if ( $all_filled ) {
// Award points via the WP Gamification API.
do_action( 'wp_gamification_trigger_rule', 'bp_profile_complete', $user_id );
}
} );
<?php
/**
* Register a "Community Champion" badge that is awarded
* when a member earns 500 or more total points.
*
* Hook: wp_gamification_register_badges
*/
add_action( 'wp_gamification_register_badges', function( $badge_registry ) {
$badge_registry->register( 'community_champion', [
'label' => __( 'Community Champion', 'my-plugin' ),
'description' => __( 'Awarded to members who have earned 500 points.', 'my-plugin' ),
'image_url' => get_template_directory_uri() . '/badges/champion.svg',
'conditions' => [
[
'type' => 'points_total',
'operator' => '>=',
'value' => 500,
],
],
'once' => true,
] );
} );
/**
* Evaluate badge conditions after every point transaction
* so the badge is awarded the moment a user crosses the threshold.
*/
add_action( 'wp_gamification_points_awarded', function( $user_id, $points, $rule_key ) {
wp_gamification_evaluate_badges( $user_id );
}, 10, 3 );
<?php
/**
* Custom shortcode that renders a leaderboard scoped to a
* specific BuddyPress group.
*
* Usage: [bp_group_leaderboard group_id="42" limit="10"]
*/
add_shortcode( 'bp_group_leaderboard', function( $atts ) {
$atts = shortcode_atts( [
'group_id' => 0,
'limit' => 10,
'period' => 'all_time', // 'weekly' | 'monthly' | 'all_time'
], $atts, 'bp_group_leaderboard' );
$group_id = absint( $atts['group_id'] );
$limit = absint( $atts['limit'] );
$period = sanitize_key( $atts['period'] );
// Fetch group members.
$members = BP_Groups_Member::get_group_member_ids( $group_id );
if ( empty( $members ) ) {
return '<p>' . esc_html__( 'No members found.', 'my-plugin' ) . '</p>';
}
// Retrieve leaderboard data from WP Gamification.
$leaderboard = wp_gamification_get_leaderboard( [
'user_ids' => $members,
'period' => $period,
'limit' => $limit,
'orderby' => 'points',
'order' => 'DESC',
] );
ob_start();
?>
<div class="bp-group-leaderboard">
<ol class="leaderboard-list">
<?php foreach ( $leaderboard as $rank => $entry ) : ?>
<li class="leaderboard-entry rank-<?php echo esc_attr( $rank + 1 ); ?>">
<?php echo bp_core_fetch_avatar( [ 'item_id' => $entry['user_id'], 'type' => 'thumb' ] ); ?>
<span class="display-name"><?php echo esc_html( bp_core_get_user_displayname( $entry['user_id'] ) ); ?></span>
<span class="points"><?php echo esc_html( number_format( $entry['points'] ) ); ?> pts</span>
</li>
<?php endforeach; ?>
</ol>
</div>
<?php
return ob_get_clean();
} );
<?php
/**
* Award points for BuddyPress social activity.
*
* Hooks into core BP activity actions to credit the actor
* with points through WP Gamification.
*/
/**
* Points for posting a status update.
*/
add_action( 'bp_activity_posted_update', function( $content, $user_id, $activity_id ) {
do_action( 'wp_gamification_trigger_rule', 'bp_status_update', $user_id );
}, 10, 3 );
/**
* Points for leaving a comment on an activity item.
*/
add_action( 'bp_activity_comment_posted', function( $comment_id, $params ) {
do_action( 'wp_gamification_trigger_rule', 'bp_activity_comment', $params['user_id'] );
}, 10, 2 );
/**
* Points for joining a BuddyPress group.
*/
add_action( 'groups_join_group', function( $group_id, $user_id ) {
do_action( 'wp_gamification_trigger_rule', 'bp_join_group', $user_id );
}, 10, 2 );
/**
* Points for making a new friendship connection.
*/
add_action( 'friends_friendship_accepted', function( $friendship_id, $initiator_id, $friend_id ) {
do_action( 'wp_gamification_trigger_rule', 'bp_friendship_made', $initiator_id );
do_action( 'wp_gamification_trigger_rule', 'bp_friendship_made', $friend_id );
}, 10, 3 );
<?php
/**
* WooCommerce reward integration with WP Gamification.
*
* 1. Award points when an order is completed.
* 2. Convert accumulated points into a WooCommerce discount coupon.
*/
/**
* Step 1 — Award purchase points on order completion.
* Rate: 1 point per $1 spent (configurable).
*/
add_action( 'woocommerce_order_status_completed', function( $order_id ) {
$order = wc_get_order( $order_id );
$user_id = $order->get_customer_id();
if ( ! $user_id ) {
return; // Guest checkout — skip.
}
$points_per_dollar = apply_filters( 'wpg_points_per_dollar', 1 );
$subtotal = (float) $order->get_subtotal();
$points_to_award = (int) floor( $subtotal * $points_per_dollar );
if ( $points_to_award > 0 ) {
wp_gamification_award_points( $user_id, $points_to_award, [
'rule' => 'wc_purchase',
'note' => sprintf( 'Order #%d — %.0f pts awarded', $order_id, $points_to_award ),
'meta' => [ 'order_id' => $order_id ],
] );
}
} );
/**
* Step 2 — Redeem points as a WooCommerce discount coupon.
*
* @param int $user_id WP user ID requesting the coupon.
* @param int $points_to_burn Number of points to redeem.
* @return string|WP_Error Coupon code or error.
*/
function wpg_redeem_points_for_coupon( int $user_id, int $points_to_burn ) {
$rate = apply_filters( 'wpg_dollars_per_point', 0.01 ); // 100 pts = $1.
$discount_amount = round( $points_to_burn * $rate, 2 );
if ( $discount_amount < 1 ) {
return new WP_Error( 'insufficient_points', __( 'Minimum redemption is 100 points.', 'my-plugin' ) );
}
$available = wp_gamification_get_user_points( $user_id );
if ( $available < $points_to_burn ) {
return new WP_Error( 'not_enough_points', __( 'Insufficient points balance.', 'my-plugin' ) );
}
// Deduct points.
wp_gamification_deduct_points( $user_id, $points_to_burn, [ 'rule' => 'wc_coupon_redemption' ] );
// Create single-use coupon.
$coupon_code = strtoupper( 'REWARD-' . substr( md5( $user_id . time() ), 0, 8 ) );
$coupon = [
'post_title' => $coupon_code,
'post_status' => 'publish',
'post_type' => 'shop_coupon',
'post_excerpt' => sprintf( 'Redeemed %d points by user %d', $points_to_burn, $user_id ),
];
$coupon_id = wp_insert_post( $coupon );
update_post_meta( $coupon_id, 'discount_type', 'fixed_cart' );
update_post_meta( $coupon_id, 'coupon_amount', $discount_amount );
update_post_meta( $coupon_id, 'usage_limit', 1 );
update_post_meta( $coupon_id, 'customer_email', [ get_userdata( $user_id )->user_email ] );
update_post_meta( $coupon_id, 'expiry_date', date( 'Y-m-d', strtotime( '+30 days' ) ) );
return $coupon_code;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment