Home / Admin / Rest_Api_DIR – Users
Duplicate Snippet

Embed Snippet on Your Site

Rest_Api_DIR – Users

ismail daugherty PRO
<10
Code Preview
php
<?php
/**
 * WPCode Snippet: Expose Users Sync ACF Fields to REST API (Application Password Auth Required)
 * Description: Makes ALL user sync data accessible ONLY via Application Password authentication
 * Location: Run Everywhere
 * Priority: 15
 * 
 * CRITICAL: This is REQUIRED for WhaleSync to access all the custom fields!
 * Without this, WhaleSync will only see basic post data, not the ACF fields.
 */
defined( 'ABSPATH' ) || exit;
/**
 * Register ALL Users Sync meta fields in REST API
 */
add_action( 'rest_api_init', function() {
    
    // ========================================
    // USERS BB SYNC CPT FIELDS
    // ========================================
    $user_fields = array(
        // ==========================================
        // TAB 1: USER OVERVIEW
        // ==========================================
        'user_id'                    => 'integer',
        'user_login'                 => 'string',
        'user_email'                 => 'string',
        'user_status'                => 'string',
        'user_roles'                 => 'string',
        'display_name'               => 'string',
        'first_name'                 => 'string',
        'last_name'                  => 'string',
        'nickname'                   => 'string',
        'phone'                      => 'string',
        'user_url'                   => 'string',
        'post_count'                 => 'integer',
        'description'                => 'string',
        'user_registered'            => 'string',
        'last_login'                 => 'string',
        'bb_last_activity'           => 'string',
        'user_edit_link'             => 'string',
        'user_profile_link'          => 'string',
        'bb_profile_link'            => 'string',
        
        // ==========================================
        // TAB 2: BUDDYBOSS PROFILE
        // ==========================================
        'bb_profile_type'            => 'string',
        'bb_profile_type_label'      => 'string',
        'bb_friend_count'            => 'integer',
        'bb_group_count'             => 'integer',
        'bb_extended_fields_count'   => 'integer',
        'bb_extended_fields_list'    => 'string',
        
        // ==========================================
        // TAB 3: WP FUSION
        // ==========================================
        'wpf_contact_id'             => 'string',
        'wpf_tags_count'             => 'integer',
        'wpf_tags_list'              => 'string',
        'wpf_tags_raw'               => 'string',
        
        // ==========================================
        // TAB 4: GRAVITY FORMS
        // ==========================================
        'gf_total_entries'           => 'integer',
        'gf_forms_completed'         => 'integer',
        'gf_last_submission'         => 'string',
        'gf_submissions_summary'     => 'string',
        'gf_entry_ids'               => 'string',
        
        // ==========================================
        // TAB 5: LIFTERLMS COURSES
        // ==========================================
        'llms_enrolled_courses'      => 'integer',
        'llms_completed_courses'     => 'integer',
        'llms_overall_progress'      => 'integer',
        'llms_overall_grade'         => 'string',
        'llms_course_details'        => 'string',
        'llms_enrolled_course_ids'   => 'string',
        'llms_completed_course_ids'  => 'string',
        
        // ==========================================
        // TAB 6: LIFTERLMS MEMBERSHIPS
        // ==========================================
        'llms_membership_count'      => 'integer',
        'llms_membership_list'       => 'string',
        'llms_membership_ids'        => 'string',
        
        // ==========================================
        // TAB 7: LIFTERLMS CERTIFICATES
        // ==========================================
        'llms_certificate_count'     => 'integer',
        'llms_achievement_count'     => 'integer',
        'llms_certificates_list'     => 'string',
        
        // ==========================================
        // TAB 8: ALL USER META
        // ==========================================
        'all_user_meta'              => 'string',
        
        // ==========================================
        // KIC CUSTOM FIELDS
        // ==========================================
        // KIC Contact Fields
        'kic_full_name'              => 'string',
        'kic_phone'                  => 'string',
        'kic_phone_secondary'        => 'string',
        
        // KIC Address Fields
        'kic_address_street'         => 'string',
        'kic_address_street_2'       => 'string',
        'kic_address_city'           => 'string',
        'kic_address_state'          => 'string',
        'kic_address_zip'            => 'string',
        
        // KIC ID Fields
        'kic_staff_id'               => 'string',
        'kic_employee_id'            => 'string',
        'kic_member_id'              => 'string',
        'kic_group_id'               => 'string',
        'kic_org_id'                 => 'string',
        'kic_scholar_id'             => 'string',
        'kic_vendor_id'              => 'string',
        'kic_intern_id'              => 'string',
        
        // KIC External System IDs
        'kic_ghl_id'                 => 'string',
        'kic_org_name'               => 'string',
        
        // KIC Address Country
        'kic_address_country'        => 'string',
        
        // KIC Additional Fields
        'kic_date_of_birth'          => 'string',
        'kic_hire_date'              => 'string',
        'kic_emergency_contact_name' => 'string',
        'kic_emergency_contact_phone' => 'string',
        
        // ==========================================
        // TAB 9: SYNC STATUS
        // ==========================================
        'whalesync_status'           => 'string',
        'last_sync'                  => 'string',
        'airtable_record_id'         => 'string',
        'sync_errors'                => 'string',
    );
    
    // Register Users Sync fields
    foreach ( $user_fields as $field_name => $field_type ) {
        register_rest_field( 'users_bb_sync', $field_name, array(
            'get_callback' => function( $object ) use ( $field_name, $field_type ) {
                $value = get_post_meta( $object['id'], $field_name, true );
                
                // Handle empty values
                if ( $value === '' || $value === false ) {
                    return null;
                }
                
                // ✅ TYPE CONVERSION - Force correct types for Airtable/WhaleSync
                switch ( $field_type ) {
                    case 'integer':
                        return intval( $value );
                    case 'boolean':
                        // Handle various boolean representations
                        if ( is_string( $value ) ) {
                            return ( $value === '1' || $value === 'true' || $value === 'yes' );
                        }
                        return (bool) $value;
                    case 'array':
                        // Ensure arrays are properly formatted
                        if ( is_string( $value ) ) {
                            // Try to decode if it's JSON
                            $decoded = json_decode( $value, true );
                            if ( json_last_error() === JSON_ERROR_NONE ) {
                                return $decoded;
                            }
                        }
                        return is_array( $value ) ? $value : array();
                    case 'object':
                        // Ensure objects are properly formatted
                        if ( is_string( $value ) ) {
                            $decoded = json_decode( $value );
                            if ( json_last_error() === JSON_ERROR_NONE ) {
                                return $decoded;
                            }
                        }
                        return is_array( $value ) || is_object( $value ) ? $value : new stdClass();
                    default:
                        // Return string values as-is
                        return strval( $value );
                }
            },
            'update_callback' => function( $value, $object ) use ( $field_name ) {
                return update_post_meta( $object->ID, $field_name, $value );
            },
            'schema' => array(
                'description' => ucwords( str_replace( '_', ' ', $field_name ) ),
                'type'        => $field_type,
                'context'     => array( 'view', 'edit' ),
            ),
        ) );
    }
    
} );
/**
 * Ensure REST API is enabled for Users Sync CPT
 */
add_filter( 'register_post_type_args', function( $args, $post_type ) {
    
    if ( $post_type === 'users_bb_sync' ) {
        $args['show_in_rest'] = true;
        $args['rest_base'] = 'users-bb-sync';
        $args['rest_controller_class'] = 'WP_REST_Posts_Controller';
        
        // Ensure custom fields support
        if ( ! in_array( 'custom-fields', $args['supports'] ) ) {
            $args['supports'][] = 'custom-fields';
        }
    }
    
    return $args;
}, 10, 2 );
/**
 * ✅ SECURITY: Block access unless using Application Password
 */
add_filter( 'rest_pre_dispatch', function( $result, $server, $request ) {
    
    // Only protect Users Sync CPT endpoints
    $route = $request->get_route();
    if ( strpos( $route, '/wp/v2/users-bb-sync' ) === false && 
         strpos( $route, '/users-sync/v1' ) === false ) {
        return $result;
    }
    
    // Check if user is authenticated
    $user = wp_get_current_user();
    
    if ( ! $user || ! $user->exists() ) {
        return new WP_Error(
            'rest_forbidden',
            __( 'Authentication required. Please use Application Password credentials.' ),
            array( 'status' => 401 )
        );
    }
    
    // ✅ CRITICAL: Check if authenticated via Application Password
    $auth_header = $request->get_header( 'authorization' );
    
    // If no auth header, they're just logged in via browser - BLOCK IT
    if ( empty( $auth_header ) ) {
        return new WP_Error(
            'rest_forbidden',
            __( 'Application Password authentication required. Browser login not allowed.' ),
            array( 'status' => 403 )
        );
    }
    
    // If they have auth header, they're using Application Password - ALLOW IT
    return $result;
    
}, 10, 3 );
/**
 * Users Sync test endpoint to verify REST API functionality
 */
add_action( 'rest_api_init', function() {
    
    // Users sync test endpoint
    register_rest_route( 'users-sync/v1', '/test', array(
        'methods'  => 'GET',
        'callback' => function() {
            
            $posts = get_posts( array(
                'post_type' => 'users_bb_sync',
                'numberposts' => 1,
            ) );
            
            if ( empty( $posts ) ) {
                return new WP_REST_Response( array(
                    'status' => 'error',
                    'message' => 'No user sync posts found. Run sync first.',
                    'sync_url' => add_query_arg( 'sync_users', '1', admin_url() ),
                ), 404 );
            }
            
            $post = $posts[0];
            
            // Get some sample meta fields
            $user_id = get_post_meta( $post->ID, 'user_id', true );
            $user_email = get_post_meta( $post->ID, 'user_email', true );
            $bb_profile_type = get_post_meta( $post->ID, 'bb_profile_type', true );
            $gf_total_entries = get_post_meta( $post->ID, 'gf_total_entries', true );
            
            return new WP_REST_Response( array(
                'status' => 'success',
                'message' => 'Users Sync REST API is working!',
                'post_info' => array(
                    'id' => $post->ID,
                    'title' => $post->post_title,
                    'user_id' => $user_id,
                    'user_email' => $user_email,
                    'bb_profile_type' => $bb_profile_type,
                    'gf_total_entries' => $gf_total_entries,
                ),
                'total_fields_available' => 50,
                'endpoints' => array(
                    'collection' => rest_url( 'wp/v2/users-bb-sync' ),
                    'single' => rest_url( 'wp/v2/users-bb-sync/' . $post->ID ),
                    'test' => rest_url( 'users-sync/v1/test' ),
                ),
            ), 200 );
        },
        'permission_callback' => '__return_true', // Test endpoint is public
    ) );
    
    // Users sync status endpoint
    register_rest_route( 'users-sync/v1', '/status', array(
        'methods'  => 'GET',
        'callback' => function() {
            
            // Check if user is authenticated with Application Password
            $user = wp_get_current_user();
            if ( ! $user || ! $user->exists() ) {
                return new WP_REST_Response( array(
                    'status' => 'error',
                    'message' => 'Authentication required.',
                ), 401 );
            }
            
            // Get sync statistics
            $total_users = count_users();
            $total_synced = wp_count_posts( 'users_bb_sync' )->publish;
            
            // Get last sync time
            $latest_sync = get_posts( array(
                'post_type' => 'users_bb_sync',
                'numberposts' => 1,
                'orderby' => 'modified',
                'order' => 'DESC',
            ) );
            
            $last_sync_time = ! empty( $latest_sync ) ? $latest_sync[0]->post_modified : 'Never';
            
            return new WP_REST_Response( array(
                'status' => 'success',
                'sync_info' => array(
                    'total_users' => $total_users['total_users'],
                    'total_synced' => $total_synced,
                    'last_sync' => $last_sync_time,
                    'sync_percentage' => $total_users['total_users'] > 0 
                        ? round( ( $total_synced / $total_users['total_users'] ) * 100, 2 ) 
                        : 0,
                ),
                'user_roles' => $total_users['avail_roles'],
            ), 200 );
        },
        'permission_callback' => function() {
            return current_user_can( 'edit_posts' );
        },
    ) );
    
} );
/**
 * Add custom REST API query parameters for Users Sync
 */
add_filter( 'rest_users_bb_sync_query', function( $args, $request ) {
    
    // Allow filtering by user_id
    if ( isset( $request['user_id'] ) ) {
        $args['meta_key'] = 'user_id';
        $args['meta_value'] = intval( $request['user_id'] );
    }
    
    // Allow filtering by user role
    if ( isset( $request['user_role'] ) ) {
        if ( ! isset( $args['meta_query'] ) ) {
            $args['meta_query'] = array();
        }
        $args['meta_query'][] = array(
            'key' => 'user_roles',
            'value' => sanitize_text_field( $request['user_role'] ),
            'compare' => 'LIKE',
        );
    }
    
    // Allow filtering by BuddyBoss profile type
    if ( isset( $request['profile_type'] ) ) {
        if ( ! isset( $args['meta_query'] ) ) {
            $args['meta_query'] = array();
        }
        $args['meta_query'][] = array(
            'key' => 'bb_profile_type',
            'value' => sanitize_text_field( $request['profile_type'] ),
            'compare' => '=',
        );
    }
    
    // Allow filtering by sync status
    if ( isset( $request['sync_status'] ) ) {
        if ( ! isset( $args['meta_query'] ) ) {
            $args['meta_query'] = array();
        }
        $args['meta_query'][] = array(
            'key' => 'whalesync_status',
            'value' => sanitize_text_field( $request['sync_status'] ),
            'compare' => '=',
        );
    }
    
    // Allow filtering by users with Gravity Forms submissions
    if ( isset( $request['has_submissions'] ) && $request['has_submissions'] ) {
        if ( ! isset( $args['meta_query'] ) ) {
            $args['meta_query'] = array();
        }
        $args['meta_query'][] = array(
            'key' => 'gf_total_entries',
            'value' => 0,
            'compare' => '>',
            'type' => 'NUMERIC',
        );
    }
    
    // Allow filtering by LifterLMS enrollment
    if ( isset( $request['has_courses'] ) && $request['has_courses'] ) {
        if ( ! isset( $args['meta_query'] ) ) {
            $args['meta_query'] = array();
        }
        $args['meta_query'][] = array(
            'key' => 'llms_enrolled_courses',
            'value' => 0,
            'compare' => '>',
            'type' => 'NUMERIC',
        );
    }
    
    // ==========================================
    // KIC FIELD FILTERS
    // ==========================================
    
    // Filter by KIC City
    if ( isset( $request['kic_city'] ) ) {
        if ( ! isset( $args['meta_query'] ) ) {
            $args['meta_query'] = array();
        }
        $args['meta_query'][] = array(
            'key' => 'kic_address_city',
            'value' => sanitize_text_field( $request['kic_city'] ),
            'compare' => '=',
        );
    }
    
    // Filter by KIC State
    if ( isset( $request['kic_state'] ) ) {
        if ( ! isset( $args['meta_query'] ) ) {
            $args['meta_query'] = array();
        }
        $args['meta_query'][] = array(
            'key' => 'kic_address_state',
            'value' => sanitize_text_field( $request['kic_state'] ),
            'compare' => '=',
        );
    }
    
    // Filter by KIC Organization ID
    if ( isset( $request['kic_org_id'] ) ) {
        if ( ! isset( $args['meta_query'] ) ) {
            $args['meta_query'] = array();
        }
        $args['meta_query'][] = array(
            'key' => 'kic_org_id',
            'value' => sanitize_text_field( $request['kic_org_id'] ),
            'compare' => '=',
        );
    }
    
    // Filter by KIC Staff ID
    if ( isset( $request['kic_staff_id'] ) ) {
        if ( ! isset( $args['meta_query'] ) ) {
            $args['meta_query'] = array();
        }
        $args['meta_query'][] = array(
            'key' => 'kic_staff_id',
            'value' => sanitize_text_field( $request['kic_staff_id'] ),
            'compare' => '=',
        );
    }
    
    // Filter by KIC Organization Name
    if ( isset( $request['kic_org_name'] ) ) {
        if ( ! isset( $args['meta_query'] ) ) {
            $args['meta_query'] = array();
        }
        $args['meta_query'][] = array(
            'key' => 'kic_org_name',
            'value' => sanitize_text_field( $request['kic_org_name'] ),
            'compare' => 'LIKE',
        );
    }
    
    return $args;
    
}, 10, 2 );
/**
 * Add collection parameters for REST API
 */
add_filter( 'rest_users_bb_sync_collection_params', function( $params ) {
    
    $params['user_id'] = array(
        'description' => 'Filter by WordPress User ID',
        'type' => 'integer',
        'sanitize_callback' => 'absint',
    );
    
    $params['user_role'] = array(
        'description' => 'Filter by user role',
        'type' => 'string',
        'sanitize_callback' => 'sanitize_text_field',
    );
    
    $params['profile_type'] = array(
        'description' => 'Filter by BuddyBoss profile type',
        'type' => 'string',
        'sanitize_callback' => 'sanitize_text_field',
    );
    
    $params['sync_status'] = array(
        'description' => 'Filter by sync status',
        'type' => 'string',
        'enum' => array( 'active', 'paused', 'error' ),
        'sanitize_callback' => 'sanitize_text_field',
    );
    
    $params['has_submissions'] = array(
        'description' => 'Filter to users with Gravity Forms submissions',
        'type' => 'boolean',
    );
    
    $params['has_courses'] = array(
        'description' => 'Filter to users enrolled in LifterLMS courses',
        'type' => 'boolean',
    );
    
    // KIC Field Filters
    $params['kic_city'] = array(
        'description' => 'Filter by KIC City field',
        'type' => 'string',
        'sanitize_callback' => 'sanitize_text_field',
    );
    
    $params['kic_state'] = array(
        'description' => 'Filter by KIC State field (2-letter code)',
        'type' => 'string',
        'sanitize_callback' => 'sanitize_text_field',
    );
    
    $params['kic_org_id'] = array(
        'description' => 'Filter by KIC Organization ID',
        'type' => 'string',
        'sanitize_callback' => 'sanitize_text_field',
    );
    
    $params['kic_staff_id'] = array(
        'description' => 'Filter by KIC Staff ID',
        'type' => 'string',
        'sanitize_callback' => 'sanitize_text_field',
    );
    
    $params['kic_org_name'] = array(
        'description' => 'Filter by KIC Organization Name',
        'type' => 'string',
        'sanitize_callback' => 'sanitize_text_field',
    );
    
    return $params;
    
} );
/**
 * Helper function to trigger sync via REST API (requires authentication)
 */
add_action( 'rest_api_init', function() {
    
    register_rest_route( 'users-sync/v1', '/sync', array(
        'methods'  => 'POST',
        'callback' => function( $request ) {
            
            // Get specific user ID if provided
            $user_id = $request->get_param( 'user_id' );
            
            if ( $user_id ) {
                // Sync single user
                $sync_instance = WPRUS_BB_Manual_Sync::get_instance();
                $result = $sync_instance->sync_single_user( intval( $user_id ) );
                
                if ( $result ) {
                    return new WP_REST_Response( array(
                        'status' => 'success',
                        'message' => 'User ' . $user_id . ' synced successfully.',
                        'post_id' => $result,
                    ), 200 );
                } else {
                    return new WP_REST_Response( array(
                        'status' => 'error',
                        'message' => 'Failed to sync user ' . $user_id,
                    ), 500 );
                }
            } else {
                // Sync all users
                $sync_instance = WPRUS_BB_Manual_Sync::get_instance();
                $synced = $sync_instance->sync_all_users();
                
                return new WP_REST_Response( array(
                    'status' => 'success',
                    'message' => 'All users synced successfully.',
                    'total_synced' => count( $synced ),
                    'user_ids' => $synced,
                ), 200 );
            }
        },
        'permission_callback' => function() {
            return current_user_can( 'manage_options' );
        },
        'args' => array(
            'user_id' => array(
                'description' => 'Optional: Specific User ID to sync',
                'type' => 'integer',
                'required' => false,
                'sanitize_callback' => 'absint',
            ),
        ),
    ) );
    
} );
/**
 * Add REST API info to admin notices
 */
add_action( 'admin_notices', function() {
    
    // Only show on Users Sync pages
    $screen = get_current_screen();
    if ( ! $screen || strpos( $screen->id, 'users_bb_sync' ) === false ) {
        return;
    }
    
    ?>
    <div class="notice notice-info">
        <p><strong>Users Sync REST API Endpoints:</strong></p>
        <ul style="list-style: disc; margin-left: 20px;">
            <li>Collection: <code><?php echo rest_url( 'wp/v2/users-bb-sync' ); ?></code></li>
            <li>Test: <code><?php echo rest_url( 'users-sync/v1/test' ); ?></code></li>
            <li>Status: <code><?php echo rest_url( 'users-sync/v1/status' ); ?></code></li>
            <li>Sync: <code><?php echo rest_url( 'users-sync/v1/sync' ); ?></code> (POST)</li>
        </ul>
        <p><em>Authentication: Application Password required for all data endpoints.</em></p>
    </div>
    <?php
} );
/**
 * Log REST API access for debugging
 */
add_filter( 'rest_request_after_callbacks', function( $response, $handler, $request ) {
    
    $route = $request->get_route();
    
    // Only log Users Sync endpoints
    if ( strpos( $route, 'users-sync' ) !== false || strpos( $route, 'users_bb_sync' ) !== false ) {
        
        // Log the access
        error_log( sprintf(
            'USERS_REST_API: %s request to %s from user %s',
            $request->get_method(),
            $route,
            wp_get_current_user()->user_login ?: 'anonymous'
        ) );
    }
    
    return $response;
    
}, 10, 3 );

Comments

Add a Comment