APP
‘GET’,
‘callback’ => [ $this, ‘get_stats’ ],
‘permission_callback’ => ‘__return_true’
]);register_rest_route( ‘bbb/v1’, ‘/ambassadors’, [
‘methods’ => ‘GET’,
‘callback’ => [ $this, ‘get_ambassadors’ ],
‘permission_callback’ => ‘__return_true’
]);register_rest_route( ‘bbb/v1’, ‘/merch’, [
‘methods’ => ‘GET’,
‘callback’ => [ $this, ‘get_merch’ ],
‘permission_callback’ => ‘__return_true’
]);register_rest_route( ‘bbb/v1’, ‘/leaderboard’, [
‘methods’ => ‘GET’,
‘callback’ => [ $this, ‘get_leaderboard’ ],
‘permission_callback’ => ‘__return_true’
]);register_rest_route( ‘bbb/v1’, ‘/campaigns’, [
‘methods’ => ‘GET’,
‘callback’ => [ $this, ‘get_campaigns’ ],
‘permission_callback’ => ‘__return_true’
]);
}// Example: aggregated stats
public function get_stats( $request ) {
// Followers: example source = option or transient. Replace as needed.
$followers = (int) get_option(‘bbb_followers_count’, 178000);
$ambassadors_count = count_users_with_role(‘ambassador’); // helper below
$wallet_total = (float) get_option(‘bbb_wallet_total’, 3480.00);
$pending = (float) get_option(‘bbb_pending_payout’, 520.00);return rest_ensure_response([
‘followers’ => $followers,
‘ambassadors’ => $ambassadors_count,
‘wallet’ => [
‘balance’ => $wallet_total,
‘pending’ => $pending
]
]);
}// List ambassadors (paged)
public function get_ambassadors( $request ) {
$paged = max(1, (int) $request->get_param(‘page’) );
$per_page = min(100, max(10, (int) $request->get_param(‘per_page’, 20)));$args = [
‘role’ => ‘ambassador’,
‘number’ => $per_page,
‘paged’ => $paged,
‘orderby’ => ‘meta_value_num’,
‘meta_key’ => ‘bbb_points’,
‘order’ => ‘DESC’
];$users = get_users($args);
$data = [];
foreach ($users as $u) {
$data[] = [
‘ID’ => $u->ID,
‘display_name’ => $u->display_name,
‘points’ => (int) get_user_meta($u->ID, ‘bbb_points’, true),
‘country’ => get_user_meta($u->ID, ‘bbb_country’, true)
];
}return rest_ensure_response([
‘page’ => $paged,
‘per_page’ => $per_page,
‘items’ => $data
]);
}// Merch product list (pull from WooCommerce if exists, fallback to custom posts)
public function get_merch( $request ) {
if ( class_exists(‘WooCommerce’) ) {
$args = [
‘status’ => ‘publish’,
‘limit’ => 50
];
$products = wc_get_products($args);
$data = [];
foreach ($products as $p) {
$data[] = [
‘id’ => $p->get_id(),
‘title’ => $p->get_name(),
‘price’ => $p->get_price(),
‘currency’ => get_woocommerce_currency(),
‘image’ => wp_get_attachment_url($p->get_image_id())
];
}
} else {
// fallback: custom post type ‘merch’
$q = get_posts([‘post_type’=>’merch’,’posts_per_page’=>50,’post_status’=>’publish’]);
$data = [];
foreach ($q as $post) {
$data[] = [
‘id’ => $post->ID,
‘title’ => get_the_title($post),
‘price’ => get_post_meta($post->ID,’price’,true),
‘image’ => get_the_post_thumbnail_url($post,’medium’)
];
}
}
return rest_ensure_response([‘items’=>$data]);
}// Leaderboard: top ambassadors by points
public function get_leaderboard( $request ) {
$top = (int) $request->get_param(‘top’) ?: 10;
$users = get_users([
‘role’ => ‘ambassador’,
‘orderby’ => ‘meta_value_num’,
‘meta_key’ => ‘bbb_points’,
‘order’ => ‘DESC’,
‘number’ => $top
]);
$data = [];
foreach ($users as $u) {
$data[] = [
‘rank’ => count_leaderboard_rank($u->ID), // optional helper
‘name’ => $u->display_name,
‘points’ => (int) get_user_meta($u->ID,’bbb_points’,true),
‘country’ => get_user_meta($u->ID,’bbb_country’,true)
];
}
return rest_ensure_response([‘items’=>$data]);
}// Campaigns summary (example)
public function get_campaigns( $request ) {
$campaigns = get_posts([‘post_type’=>’bbb_campaign’,’posts_per_page’=>20,’post_status’=>’publish’]);
$data = [];
foreach ($campaigns as $c) {
$data[] = [
‘id’ => $c->ID,
‘title’ => get_the_title($c),
‘entries’ => (int) get_post_meta($c->ID,’entries’,true)
];
}
return rest_ensure_response([‘items’=>$data]);
}}// helper functions (simple implementations)
function count_users_with_role($role = ‘ambassador’) {
$r = count_users();
// Better: use WP_User_Query
$q = new WP_User_Query([‘role’=>$role,’fields’=>’ID’]);
$users = $q->get_results();
return is_array($users) ? count($users) : 0;
}function count_leaderboard_rank($user_id) {
// naive: rank by points descending
global $wpdb;
$meta_key = ‘bbb_points’;
$user_points = (int) get_user_meta($user_id, $meta_key, true);
$count = $wpdb->get_var( $wpdb->prepare(
“SELECT COUNT(user_id) FROM $wpdb->usermeta WHERE meta_key=%s AND CAST(meta_value AS UNSIGNED) > %d”,
$meta_key, $user_points
) );
return (int)$count + 1;
}new BBB_API_Bridge(); ‘GET’,
‘callback’ => ‘bbb_public_stats’,
‘permission_callback’ => ‘__return_true’,
]);// Protected: wallet info
register_rest_route(‘bbb/v1’, ‘/wallet’, [
‘methods’ => ‘GET’,
‘callback’ => ‘bbb_get_wallet’,
‘permission_callback’ => function() {
return bbb_check_jwt_user();
}
]);// Protected: update points (admin or system)
register_rest_route(‘bbb/v1’, ‘/points/update’, [
‘methods’ => ‘POST’,
‘callback’ => ‘bbb_update_points’,
‘permission_callback’ => function() {
return current_user_can(‘manage_options’) || bbb_check_jwt_user();
}
]);// Protected: create payout request
register_rest_route(‘bbb/v1’, ‘/payout/request’, [
‘methods’ => ‘POST’,
‘callback’ => ‘bbb_request_payout’,
‘permission_callback’ => function() {
return bbb_check_jwt_user();
}
]);
});// Public stats (simple)
function bbb_public_stats() {
return rest_ensure_response([
‘followers’ => (int) get_option(‘bbb_followers_count’, 178000),
‘ambassadors’ => bbb_count_role(‘ambassador’),
‘campaigns’ => (int) get_option(‘bbb_campaign_count’, 7)
]);
}// Protected wallet retrieval
function bbb_get_wallet($request) {
$user = bbb_get_jwt_user();
if (!$user) return new WP_Error(‘unauthorized’, ‘Invalid token’, [‘status’=>401]);$balance = (float) get_user_meta($user->ID, ‘bbb_wallet_balance’, true) ?: 0;
$pending = (float) get_user_meta($user->ID, ‘bbb_wallet_pending’, true) ?: 0;return rest_ensure_response([
‘user_id’ => $user->ID,
‘balance’ => $balance,
‘pending’ => $pending
]);
}// Update points (admin or system)
function bbb_update_points($request) {
$params = $request->get_json_params();
$user_id = intval($params[‘user_id’]);
$delta = intval($params[‘delta’]);if (!$user_id || !$delta) return new WP_Error(‘bad_request’,’Missing params’,[‘status’=>400]);$cur = intval(get_user_meta($user_id,’bbb_points’,true));
$new = $cur + $delta;
update_user_meta($user_id,’bbb_points’,$new);return rest_ensure_response([‘user_id’=>$user_id,’points’=>$new]);
}// Payout request (creates a CPT or DB row; simplified here)
function bbb_request_payout($request) {
$user = bbb_get_jwt_user();
$params = $request->get_json_params();
$amount = floatval($params[‘amount’]);
if ($amount <= 0) return new WP_Error('bad_request','Invalid amount',['status'=>400]);// Example: store as post type ‘bbb_payout_request’ or user meta list
$post_id = wp_insert_post([
‘post_title’ => ‘Payout for user ‘.$user->ID.’ – ‘.date(‘Y-m-d H:i:s’),
‘post_type’ => ‘bbb_payout_request’,
‘post_status’ => ‘pending’,
‘post_content’ => ‘Amount: ‘.$amount,
‘meta_input’ => [‘user_id’=>$user->ID,’amount’=>$amount]
]);// mark pending, subtract from available balance if desired (business logic)
$pending = (float) get_user_meta($user->ID,’bbb_wallet_pending’,true) ?: 0;
update_user_meta($user->ID,’bbb_wallet_pending’,$pending + $amount);return rest_ensure_response([‘request_id’=>$post_id,’status’=>’pending’]);
}/* ———- helper functions ———- */
function bbb_check_jwt_user() {
// Use jwt auth plugin’s authenticated user
if (!empty($GLOBALS[‘current_user’]) && $GLOBALS[‘current_user’]->ID) return true;// try to read Authorization header token
$user = bbb_get_jwt_user();
return $user ? true : false;
}function bbb_get_jwt_user() {
// jwt plugin sets the current user; if not present, try decoding token
if (!empty($GLOBALS[‘current_user’]) && $GLOBALS[‘current_user’]->ID) return $GLOBALS[‘current_user’];$header = null;
if (isset($_SERVER[‘HTTP_AUTHORIZATION’])) $header = trim($_SERVER[‘HTTP_AUTHORIZATION’]);
elseif (function_exists(‘getallheaders’)) {
$headers = getallheaders();
if (!empty($headers[‘Authorization’])) $header = $headers[‘Authorization’];
}
if (!$header) return null;
if (preg_match(‘/Bearer\s(\S+)/’, $header, $matches)) {
$token = $matches[1];
// Let jwt-auth plugin decode and authenticate, but easiest: call their validate endpoint or rely on plugin setting current user
// If plugin is active, it should have set the global current_user on rest request
if (!empty($GLOBALS[‘current_user’]) && $GLOBALS[‘current_user’]->ID) return $GLOBALS[‘current_user’];
}
return null;
}function bbb_count_role($role=’ambassador’){
$q = new WP_User_Query([‘role’=>$role,’count_total’=>true]);
return $q->get_total();
}