Created
April 10, 2026 08:53
-
-
Save vapvarun/ecf1caed630bd46350b707aaeffa3a02 to your computer and use it in GitHub Desktop.
Add Points, Badges and Leaderboards to BuddyPress with WP Gamification (bpcustomdev.com)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?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', | |
| ] ); | |
| } ); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?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 ); | |
| } | |
| } ); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?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 ); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?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(); | |
| } ); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?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 ); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?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