Home / Admin / SYNC_DIR – Users
Duplicate Snippet

Embed Snippet on Your Site

SYNC_DIR – Users

ismail daugherty PRO
<10
Code Preview
php
<?php
/**
 * WPCode Snippet: WordPress Users Sync - FINAL NO DUPLICATES VERSION
 * Description: Bulletproof manual sync with guaranteed no duplicate posts
 * Location: Run Everywhere
 * Priority: 20
 * Version: 5.0 FINAL - Complete rewrite with duplicate prevention
 * 
 * GUARANTEE: Each user gets exactly ONE sync post - no duplicates ever!
 */
defined( 'ABSPATH' ) || exit;
/**
 * ========================================
 * CORE SYNC CLASS - NO DUPLICATES VERSION
 * ========================================
 */
class WPRUS_BB_Manual_Sync {
    
    private static $instance = null;
    
    public static function get_instance() {
        if ( null === self::$instance ) {
            self::$instance = new self();
        }
        return self::$instance;
    }
    
    private function __construct() {
        add_action( 'admin_bar_menu', [ $this, 'add_admin_bar_button' ], 999 );
        add_action( 'admin_init', [ $this, 'handle_manual_sync' ] );
        add_action( 'wp_ajax_sync_single_user', [ $this, 'ajax_sync_single_user' ] );
    }
    
    /**
     * ========================================
     * MANUAL SYNC CONTROLS
     * ========================================
     */
    
    public function add_admin_bar_button( $admin_bar ) {
        if ( ! current_user_can( 'manage_options' ) ) {
            return;
        }
        
        $admin_bar->add_node( [
            'id'    => 'sync-users-bb',
            'title' => '👤 Sync Users',
            'href'  => add_query_arg( [
                'sync_users' => '1',
                '_wpnonce' => wp_create_nonce( 'sync_users_bb' )
            ], admin_url() ),
            'meta'  => [
                'title' => 'Manually sync all users to custom post type',
            ],
        ] );
    }
    
    public function handle_manual_sync() {
        if ( ! isset( $_GET['sync_users'] ) || ! current_user_can( 'manage_options' ) ) {
            return;
        }
        
        if ( ! wp_verify_nonce( $_GET['_wpnonce'] ?? '', 'sync_users_bb' ) ) {
            wp_die( 'Security check failed' );
        }
        
        $user_id = isset( $_GET['user_id'] ) ? intval( $_GET['user_id'] ) : 0;
        
        if ( $user_id > 0 ) {
            $result = $this->sync_single_user( $user_id );
            $message = $result ? "User #{$user_id} synced successfully!" : "Failed to sync user #{$user_id}";
        } else {
            $result = $this->sync_all_users();
            $count = is_array( $result ) ? count( $result ) : 0;
            $message = "Synced {$count} users successfully!";
        }
        
        add_action( 'admin_notices', function() use ( $message ) {
            echo '<div class="notice notice-success is-dismissible">';
            echo '<p><strong>User Sync Complete:</strong> ' . esc_html( $message ) . '</p>';
            echo '</div>';
        } );
    }
    
    /**
     * ========================================
     * MAIN SYNC FUNCTIONS
     * ========================================
     */
    
    public function sync_all_users() {
        $args = [
            'fields' => 'ID',
            'number' => -1,
        ];
        
        $user_ids = get_users( $args );
        $synced = [];
        
        foreach ( $user_ids as $user_id ) {
            try {
                if ( $this->sync_single_user( $user_id ) ) {
                    $synced[] = $user_id;
                }
            } catch ( Exception $e ) {
                error_log( "User sync failed for ID {$user_id}: " . $e->getMessage() );
            }
        }
        
        return $synced;
    }
    
    public function sync_single_user( $user_id ) {
        $user = get_userdata( $user_id );
        
        if ( ! $user ) {
            return false;
        }
        
        // Get or create sync post - THIS IS THE CRITICAL FUNCTION
        $sync_post_id = $this->get_or_create_sync_post( $user );
        
        if ( ! $sync_post_id ) {
            return false;
        }
        
        // Update all sections with error handling
        try {
            $this->update_user_overview( $sync_post_id, $user );
            $this->update_buddyboss_data( $sync_post_id, $user_id );
            $this->update_wpfusion_data( $sync_post_id, $user_id );
            $this->update_gravity_forms_data( $sync_post_id, $user_id );
            $this->update_lifterlms_data( $sync_post_id, $user_id );
            $this->update_user_meta_dump( $sync_post_id, $user_id );
            $this->update_sync_status( $sync_post_id );
        } catch ( Exception $e ) {
            error_log( "Sync error for user {$user_id}: " . $e->getMessage() );
            update_field( 'sync_errors', $e->getMessage(), $sync_post_id );
        }
        
        return $sync_post_id;
    }
    
    /**
     * ========================================
     * CRITICAL: GET OR CREATE SYNC POST - NO DUPLICATES
     * ========================================
     */
    private function get_or_create_sync_post( $user ) {
        global $wpdb;
        
        // METHOD 1: Query using ACF meta_query (most reliable for ACF fields)
        $args = [
            'post_type'      => 'users_bb_sync',
            'posts_per_page' => 1,  // We only need one
            'post_status'    => 'any', // Check all statuses
            'meta_query'     => [
                [
                    'key'     => 'user_id',  // ACF field name
                    'value'   => $user->ID,
                    'compare' => '=',
                    'type'    => 'NUMERIC'
                ]
            ],
            'suppress_filters' => false, // Allow ACF to hook in
        ];
        
        $existing_posts = get_posts( $args );
        
        // METHOD 2: If not found, try direct database query (handles ACF field key variations)
        if ( empty( $existing_posts ) ) {
            // ACF might store as field_XXX_user_id or _user_id
            $sql = $wpdb->prepare(
                "SELECT DISTINCT p.ID 
                FROM {$wpdb->posts} p
                INNER JOIN {$wpdb->postmeta} pm ON p.ID = pm.post_id
                WHERE p.post_type = %s
                AND p.post_status IN ('publish', 'draft', 'private', 'trash')
                AND (
                    (pm.meta_key = %s AND pm.meta_value = %s)
                    OR (pm.meta_key LIKE %s AND pm.meta_value = %s)
                )
                LIMIT 1",
                'users_bb_sync',
                'user_id',
                $user->ID,
                '%user_id', // Matches field_XXX_user_id
                $user->ID
            );
            
            $existing_id = $wpdb->get_var( $sql );
            
            if ( $existing_id ) {
                $existing_posts = [ get_post( $existing_id ) ];
            }
        }
        
        // METHOD 3: Also check if there's already a post with matching title (fallback)
        if ( empty( $existing_posts ) ) {
            $title_to_check = $user->display_name ?: $user->user_login;
            
            $existing_by_title = get_posts( [
                'post_type'      => 'users_bb_sync',
                'posts_per_page' => 1,
                'post_status'    => 'any',
                'title'          => $title_to_check,
                's'              => $title_to_check, // Also search content
            ] );
            
            // Only use title match if we can verify it's the same user
            if ( ! empty( $existing_by_title ) ) {
                $check_id = get_field( 'user_id', $existing_by_title[0]->ID );
                if ( $check_id == $user->ID ) {
                    $existing_posts = $existing_by_title;
                }
            }
        }
        
        // If we found an existing post, update it
        if ( ! empty( $existing_posts ) && is_object( $existing_posts[0] ) ) {
            $post_id = $existing_posts[0]->ID;
            
            // Log that we're updating
            error_log( "Updating existing sync post ID {$post_id} for user {$user->ID}" );
            
            // Update the post title and ensure it's published
            wp_update_post( [
                'ID'          => $post_id,
                'post_title'  => $user->display_name ?: $user->user_login,
                'post_status' => 'publish',
            ] );
            
            // CRITICAL: Always update the user_id field to ensure it's set
            update_field( 'user_id', $user->ID, $post_id );
            
            return $post_id;
        }
        
        // No existing post found - create new one
        error_log( "Creating new sync post for user {$user->ID}" );
        
        $post_id = wp_insert_post( [
            'post_type'   => 'users_bb_sync',
            'post_title'  => $user->display_name ?: $user->user_login,
            'post_status' => 'publish',
            'post_author' => 1,
        ] );
        
        if ( ! is_wp_error( $post_id ) && $post_id ) {
            // CRITICAL: Immediately set the user_id to prevent duplicates
            update_field( 'user_id', $user->ID, $post_id );
            
            // Also set it as regular post meta for redundancy
            update_post_meta( $post_id, 'user_id', $user->ID );
            
            error_log( "Created new sync post ID {$post_id} for user {$user->ID}" );
        }
        
        return $post_id;
    }
    
    /**
     * ========================================
     * TAB 1: USER OVERVIEW DATA
     * ========================================
     */
    private function update_user_overview( $post_id, $user ) {
        // Basic info with null safety
        update_field( 'user_id', $user->ID, $post_id );
        update_field( 'user_login', $user->user_login ?: '', $post_id );
        update_field( 'user_email', $user->user_email ?: '', $post_id );
        update_field( 'display_name', $user->display_name ?: '', $post_id );
        update_field( 'first_name', $user->first_name ?: '', $post_id );
        update_field( 'last_name', $user->last_name ?: '', $post_id );
        update_field( 'nickname', $user->nickname ?: '', $post_id );
        
        // Contact info
        update_field( 'phone', get_user_meta( $user->ID, 'phone', true ) ?: '', $post_id );
        update_field( 'user_url', $user->user_url ?: '', $post_id );
        
        // Bio and posts
        update_field( 'description', $user->description ?: '', $post_id );
        update_field( 'post_count', count_user_posts( $user->ID ) ?: 0, $post_id );
        
        // Roles
        $roles = ! empty( $user->roles ) ? implode( ', ', $user->roles ) : '';
        update_field( 'user_roles', $roles, $post_id );
        
        // Status
        $status = get_user_meta( $user->ID, 'account_status', true ) === 'inactive' ? 'inactive' : 'active';
        update_field( 'user_status', $status, $post_id );
        
        // Links
        update_field( 'user_edit_link', admin_url( "user-edit.php?user_id={$user->ID}" ), $post_id );
        update_field( 'user_profile_link', get_author_posts_url( $user->ID ), $post_id );
        
        // BuddyBoss profile link
        if ( function_exists( 'bp_core_get_user_domain' ) ) {
            $bb_link = bp_core_get_user_domain( $user->ID );
            update_field( 'bb_profile_link', $bb_link ?: '', $post_id );
        }
        
        // Dates
        update_field( 'user_registered', $user->user_registered ?: '', $post_id );
        
        // Last login
        $last_login = '';
        $login_meta_keys = [ 'wp_last_login', 'last_login', '_last_login' ];
        
        foreach ( $login_meta_keys as $key ) {
            $login_time = get_user_meta( $user->ID, $key, true );
            if ( $login_time ) {
                $last_login = is_numeric( $login_time ) 
                    ? date( 'Y-m-d H:i:s', $login_time ) 
                    : $login_time;
                break;
            }
        }
        
        update_field( 'last_login', $last_login, $post_id );
        
        // BuddyBoss last activity
        if ( function_exists( 'bp_get_user_last_activity' ) ) {
            $bb_activity = bp_get_user_last_activity( $user->ID );
            update_field( 'bb_last_activity', $bb_activity ?: '', $post_id );
        }
        
        // ========================================
        // KIC CUSTOM FIELDS
        // ========================================
        
        // KIC Contact Fields
        update_field( 'kic_full_name', get_user_meta( $user->ID, 'kic_full_name', true ) ?: '', $post_id );
        update_field( 'kic_phone', get_user_meta( $user->ID, 'kic_phone', true ) ?: '', $post_id );
        update_field( 'kic_phone_secondary', get_user_meta( $user->ID, 'kic_phone_secondary', true ) ?: '', $post_id );
        
        // KIC Address Fields
        update_field( 'kic_address_street', get_user_meta( $user->ID, 'kic_address_street', true ) ?: '', $post_id );
        update_field( 'kic_address_street_2', get_user_meta( $user->ID, 'kic_address_street_2', true ) ?: '', $post_id );
        update_field( 'kic_address_city', get_user_meta( $user->ID, 'kic_address_city', true ) ?: '', $post_id );
        update_field( 'kic_address_state', get_user_meta( $user->ID, 'kic_address_state', true ) ?: '', $post_id );
        update_field( 'kic_address_zip', get_user_meta( $user->ID, 'kic_address_zip', true ) ?: '', $post_id );
        
        // KIC ID Fields
        update_field( 'kic_staff_id', get_user_meta( $user->ID, 'kic_staff_id', true ) ?: '', $post_id );
        update_field( 'kic_employee_id', get_user_meta( $user->ID, 'kic_employee_id', true ) ?: '', $post_id );
        update_field( 'kic_member_id', get_user_meta( $user->ID, 'kic_member_id', true ) ?: '', $post_id );
        update_field( 'kic_group_id', get_user_meta( $user->ID, 'kic_group_id', true ) ?: '', $post_id );
        update_field( 'kic_org_id', get_user_meta( $user->ID, 'kic_org_id', true ) ?: '', $post_id );
        update_field( 'kic_scholar_id', get_user_meta( $user->ID, 'kic_scholar_id', true ) ?: '', $post_id );
        update_field( 'kic_vendor_id', get_user_meta( $user->ID, 'kic_vendor_id', true ) ?: '', $post_id );
        update_field( 'kic_intern_id', get_user_meta( $user->ID, 'kic_intern_id', true ) ?: '', $post_id );
        
        // KIC External System IDs
        update_field( 'kic_ghl_id', get_user_meta( $user->ID, 'kic_ghl_id', true ) ?: '', $post_id );
        update_field( 'kic_org_name', get_user_meta( $user->ID, 'kic_org_name', true ) ?: '', $post_id );
        
        // KIC Address Country (with US default)
        $country = get_user_meta( $user->ID, 'kic_address_country', true );
        update_field( 'kic_address_country', $country ?: 'US', $post_id );
        
        // KIC Additional Fields
        update_field( 'kic_date_of_birth', get_user_meta( $user->ID, 'kic_date_of_birth', true ) ?: '', $post_id );
        update_field( 'kic_hire_date', get_user_meta( $user->ID, 'kic_hire_date', true ) ?: '', $post_id );
        update_field( 'kic_emergency_contact_name', get_user_meta( $user->ID, 'kic_emergency_contact_name', true ) ?: '', $post_id );
        update_field( 'kic_emergency_contact_phone', get_user_meta( $user->ID, 'kic_emergency_contact_phone', true ) ?: '', $post_id );
    }
    
    /**
     * ========================================
     * TAB 2: BUDDYBOSS PROFILE DATA
     * ========================================
     */
    private function update_buddyboss_data( $post_id, $user_id ) {
        if ( ! function_exists( 'buddypress' ) ) {
            return;
        }
        
        // Profile type
        if ( function_exists( 'bp_get_member_type' ) ) {
            $member_types = bp_get_member_type( $user_id, false );
            if ( is_array( $member_types ) && ! empty( $member_types ) ) {
                $type = $member_types[0];
                update_field( 'bb_profile_type', $type, $post_id );
                
                $type_obj = bp_get_member_type_object( $type );
                if ( $type_obj && isset( $type_obj->labels['name'] ) ) {
                    update_field( 'bb_profile_type_label', $type_obj->labels['name'], $post_id );
                }
            }
        }
        
        // Friend count
        if ( function_exists( 'friends_get_friend_count_for_user' ) ) {
            $friend_count = friends_get_friend_count_for_user( $user_id );
            update_field( 'bb_friend_count', intval( $friend_count ), $post_id );
        }
        
        // Group count - FIXED
        if ( function_exists( 'bp_get_user_groups' ) ) {
            $groups = bp_get_user_groups( $user_id );
            $group_count = 0;
            
            if ( is_array( $groups ) && isset( $groups['groups'] ) ) {
                $group_count = is_array( $groups['groups'] ) ? count( $groups['groups'] ) : 0;
            }
            
            update_field( 'bb_group_count', $group_count, $post_id );
        }
        
        // Extended profile fields - FIXED
        if ( function_exists( 'bp_get_profile_field_data' ) ) {
            global $wpdb;
            
            $fields_data = [];
            $field_count = 0;
            
            $table_name = $wpdb->prefix . 'bp_xprofile_fields';
            
            // Check if table exists
            if ( $wpdb->get_var( $wpdb->prepare( "SHOW TABLES LIKE %s", $table_name ) ) ) {
                $fields = $wpdb->get_results( "
                    SELECT f.id, f.name, f.type 
                    FROM {$table_name} f 
                    WHERE f.parent_id = 0
                " );
                
                if ( is_array( $fields ) ) {
                    foreach ( $fields as $field ) {
                        if ( ! isset( $field->id ) || ! isset( $field->name ) ) {
                            continue;
                        }
                        
                        $value = bp_get_profile_field_data( [
                            'field'   => $field->id,
                            'user_id' => $user_id,
                        ] );
                        
                        if ( ! empty( $value ) ) {
                            $field_count++;
                            $fields_data[] = sanitize_text_field( $field->name ) . ': ' . sanitize_text_field( $value );
                        }
                    }
                }
            }
            
            update_field( 'bb_extended_fields_count', $field_count, $post_id );
            update_field( 'bb_extended_fields_list', implode( "\n", $fields_data ), $post_id );
        }
    }
    
    /**
     * ========================================
     * TAB 3: WP FUSION DATA
     * ========================================
     */
    private function update_wpfusion_data( $post_id, $user_id ) {
        if ( ! function_exists( 'wp_fusion' ) ) {
            return;
        }
        
        try {
            // Contact ID
            $contact_id = '';
            if ( isset( wp_fusion()->crm->slug ) ) {
                $contact_id = get_user_meta( $user_id, wp_fusion()->crm->slug . '_contact_id', true );
            }
            update_field( 'wpf_contact_id', $contact_id ?: '', $post_id );
            
            // Get tags
            if ( function_exists( 'wpf_get_tags' ) ) {
                $tags = wpf_get_tags( $user_id );
                
                if ( ! empty( $tags ) && is_array( $tags ) ) {
                    update_field( 'wpf_tags_count', count( $tags ), $post_id );
                    update_field( 'wpf_tags_raw', implode( ',', $tags ), $post_id );
                    
                    $available_tags = [];
                    if ( isset( wp_fusion()->settings ) && method_exists( wp_fusion()->settings, 'get' ) ) {
                        $available_tags = wp_fusion()->settings->get( 'available_tags', [] );
                    }
                    
                    $tag_labels = [];
                    foreach ( $tags as $tag_id ) {
                        if ( isset( $available_tags[ $tag_id ] ) ) {
                            $tag_labels[] = sanitize_text_field( $available_tags[ $tag_id ] );
                        } else {
                            $tag_labels[] = "Tag #{$tag_id}";
                        }
                    }
                    
                    update_field( 'wpf_tags_list', implode( "\n", $tag_labels ), $post_id );
                } else {
                    update_field( 'wpf_tags_count', 0, $post_id );
                    update_field( 'wpf_tags_raw', '', $post_id );
                    update_field( 'wpf_tags_list', 'No tags applied', $post_id );
                }
            }
        } catch ( Exception $e ) {
            error_log( "WP Fusion sync error: " . $e->getMessage() );
            update_field( 'wpf_tags_list', 'Error loading WP Fusion data', $post_id );
        }
    }
    
    /**
     * ========================================
     * TAB 4: GRAVITY FORMS DATA
     * ========================================
     */
    private function update_gravity_forms_data( $post_id, $user_id ) {
        if ( ! class_exists( 'GFAPI' ) ) {
            return;
        }
        
        try {
            $forms = GFAPI::get_forms();
            
            if ( ! is_array( $forms ) ) {
                $forms = [];
            }
            
            $user_forms = [];
            $all_entry_ids = [];
            $total_entries = 0;
            $latest_date = '';
            
            foreach ( $forms as $form ) {
                if ( ! isset( $form['id'] ) || ! isset( $form['title'] ) ) {
                    continue;
                }
                
                $search_criteria = [
                    'field_filters' => [
                        [
                            'key'   => 'created_by',
                            'value' => $user_id,
                        ]
                    ]
                ];
                
                $paging = [
                    'offset'    => 0,
                    'page_size' => 999,
                ];
                
                $entries = GFAPI::get_entries( $form['id'], $search_criteria, null, $paging );
                
                if ( ! empty( $entries ) && is_array( $entries ) && ! is_wp_error( $entries ) ) {
                    $entry_ids = [];
                    $latest_entry_date = '';
                    
                    foreach ( $entries as $entry ) {
                        if ( ! isset( $entry['id'] ) ) {
                            continue;
                        }
                        
                        $entry_ids[] = $entry['id'];
                        $all_entry_ids[] = $entry['id'];
                        
                        if ( isset( $entry['date_created'] ) && $entry['date_created'] > $latest_entry_date ) {
                            $latest_entry_date = $entry['date_created'];
                        }
                        
                        if ( isset( $entry['date_created'] ) && $entry['date_created'] > $latest_date ) {
                            $latest_date = $entry['date_created'];
                        }
                    }
                    
                    $total_entries += count( $entries );
                    
                    $user_forms[] = [
                        'form_id'     => $form['id'],
                        'form_title'  => sanitize_text_field( $form['title'] ),
                        'entry_count' => count( $entries ),
                        'entry_ids'   => $entry_ids,
                        'latest_date' => $latest_entry_date,
                    ];
                }
            }
            
            // Update fields
            update_field( 'gf_total_entries', $total_entries, $post_id );
            update_field( 'gf_forms_completed', count( $user_forms ), $post_id );
            update_field( 'gf_last_submission', $latest_date, $post_id );
            update_field( 'gf_entry_ids', implode( ',', $all_entry_ids ), $post_id );
            
            // Build summary
            if ( ! empty( $user_forms ) ) {
                $summary = "=== GRAVITY FORMS SUBMISSIONS ===\n";
                $summary .= "Total: {$total_entries} entries across " . count( $user_forms ) . " forms\n\n";
                
                foreach ( $user_forms as $form_data ) {
                    $summary .= "📋 {$form_data['form_title']} (Form #{$form_data['form_id']})\n";
                    $summary .= "   Submissions: {$form_data['entry_count']}\n";
                    
                    if ( ! empty( $form_data['latest_date'] ) ) {
                        $formatted_date = date( 'M j, Y g:i A', strtotime( $form_data['latest_date'] ) );
                        $summary .= "   Latest: {$formatted_date}\n";
                    }
                    
                    $display_ids = array_slice( $form_data['entry_ids'], 0, 10 );
                    $summary .= "   Entry IDs: " . implode( ', ', $display_ids );
                    
                    if ( count( $form_data['entry_ids'] ) > 10 ) {
                        $summary .= " (+" . ( count( $form_data['entry_ids'] ) - 10 ) . " more)";
                    }
                    $summary .= "\n";
                    
                    $admin_url = admin_url( "admin.php?page=gf_entries&id={$form_data['form_id']}&filter=created_by&field_id=created_by&operator=is&s={$user_id}" );
                    $summary .= "   View All: {$admin_url}\n\n";
                }
            } else {
                $summary = "No Gravity Forms submissions found for this user.";
            }
            
            update_field( 'gf_submissions_summary', $summary, $post_id );
            
        } catch ( Exception $e ) {
            error_log( "Gravity Forms sync error: " . $e->getMessage() );
            update_field( 'gf_submissions_summary', 'Error loading Gravity Forms data', $post_id );
        }
    }
    
    /**
     * ========================================
     * TAB 5-7: LIFTERLMS DATA - COMPLETELY FIXED
     * ========================================
     */
    private function update_lifterlms_data( $post_id, $user_id ) {
        if ( ! function_exists( 'llms_get_student' ) ) {
            return;
        }
        
        try {
            $student = llms_get_student( $user_id );
            
            if ( ! $student || ! is_object( $student ) ) {
                update_field( 'llms_enrolled_courses', 0, $post_id );
                update_field( 'llms_completed_courses', 0, $post_id );
                update_field( 'llms_course_details', 'No LifterLMS data available', $post_id );
                return;
            }
            
            // COURSES DATA - Safe handling
            $enrolled_count = 0;
            $enrolled_ids = [];
            $course_details = [];
            
            if ( method_exists( $student, 'get_courses' ) ) {
                $enrolled_courses = $student->get_courses( [
                    'limit' => 999,
                    'status' => 'enrolled',
                ] );
                
                if ( is_array( $enrolled_courses ) ) {
                    if ( isset( $enrolled_courses['results'] ) && is_array( $enrolled_courses['results'] ) ) {
                        $enrolled_ids = $enrolled_courses['results'];
                        $enrolled_count = count( $enrolled_ids );
                        
                        // Get course details safely
                        foreach ( $enrolled_ids as $course_id ) {
                            if ( ! is_numeric( $course_id ) ) {
                                continue;
                            }
                            
                            try {
                                if ( class_exists( 'LLMS_Course' ) ) {
                                    $course = new LLMS_Course( $course_id );
                                    
                                    if ( $course && method_exists( $course, 'get' ) ) {
                                        $title = $course->get( 'title' ) ?: "Course #{$course_id}";
                                        $progress = 0;
                                        $grade = 'N/A';
                                        
                                        if ( method_exists( $student, 'get_progress' ) ) {
                                            $progress = $student->get_progress( $course_id, 'course' ) ?: 0;
                                        }
                                        
                                        if ( method_exists( $student, 'get_grade' ) ) {
                                            $grade = $student->get_grade( $course_id ) ?: 'N/A';
                                        }
                                        
                                        $course_details[] = sanitize_text_field( $title ) . ": {$progress}% complete, Grade: {$grade}";
                                    }
                                }
                            } catch ( Exception $e ) {
                                error_log( "Error processing course {$course_id}: " . $e->getMessage() );
                            }
                        }
                    }
                }
            }
            
            // COMPLETED COURSES - Safe handling
            $completed_count = 0;
            $completed_ids = [];
            
            if ( method_exists( $student, 'get_completed_courses' ) ) {
                $completed_courses = $student->get_completed_courses( [
                    'limit' => 999,
                ] );
                
                if ( is_array( $completed_courses ) ) {
                    if ( isset( $completed_courses['courses'] ) && is_array( $completed_courses['courses'] ) ) {
                        $completed_ids = $completed_courses['courses'];
                        $completed_count = count( $completed_ids );
                    }
                }
            }
            
            // Update course fields
            update_field( 'llms_enrolled_courses', $enrolled_count, $post_id );
            update_field( 'llms_completed_courses', $completed_count, $post_id );
            update_field( 'llms_enrolled_course_ids', implode( ',', $enrolled_ids ), $post_id );
            update_field( 'llms_completed_course_ids', implode( ',', $completed_ids ), $post_id );
            update_field( 'llms_course_details', ! empty( $course_details ) ? implode( "\n", $course_details ) : 'No course details available', $post_id );
            
            // Overall progress and grade - Safe handling
            $overall_progress = 0;
            $overall_grade = '';
            
            if ( method_exists( $student, 'get_overall_progress' ) ) {
                $progress_value = $student->get_overall_progress();
                $overall_progress = is_numeric( $progress_value ) ? intval( $progress_value ) : 0;
            }
            
            if ( method_exists( $student, 'get_overall_grade' ) ) {
                $grade_value = $student->get_overall_grade();
                $overall_grade = is_string( $grade_value ) ? $grade_value : '';
            }
            
            update_field( 'llms_overall_progress', $overall_progress, $post_id );
            update_field( 'llms_overall_grade', $overall_grade, $post_id );
            
            // MEMBERSHIPS DATA - Safe handling
            $membership_count = 0;
            $membership_ids = [];
            $membership_list = [];
            
            if ( method_exists( $student, 'get_memberships' ) ) {
                $memberships = $student->get_memberships( [
                    'limit' => 999,
                ] );
                
                if ( is_array( $memberships ) && isset( $memberships['results'] ) && is_array( $memberships['results'] ) ) {
                    $membership_ids = $memberships['results'];
                    $membership_count = count( $membership_ids );
                    
                    foreach ( $membership_ids as $membership_id ) {
                        if ( ! is_numeric( $membership_id ) ) {
                            continue;
                        }
                        
                        try {
                            if ( class_exists( 'LLMS_Membership' ) ) {
                                $membership = new LLMS_Membership( $membership_id );
                                
                                if ( $membership && method_exists( $membership, 'get' ) ) {
                                    $title = $membership->get( 'title' ) ?: "Membership #{$membership_id}";
                                    $enrollment_date = 'Unknown';
                                    
                                    if ( method_exists( $student, 'get_enrollment_date' ) ) {
                                        $date = $student->get_enrollment_date( $membership_id );
                                        $enrollment_date = $date ?: 'Unknown';
                                    }
                                    
                                    $membership_list[] = sanitize_text_field( $title ) . " (Enrolled: {$enrollment_date})";
                                }
                            }
                        } catch ( Exception $e ) {
                            error_log( "Error processing membership {$membership_id}: " . $e->getMessage() );
                        }
                    }
                }
            }
            
            update_field( 'llms_membership_count', $membership_count, $post_id );
            update_field( 'llms_membership_ids', implode( ',', $membership_ids ), $post_id );
            update_field( 'llms_membership_list', ! empty( $membership_list ) ? implode( "\n", $membership_list ) : 'No memberships', $post_id );
            
            // CERTIFICATES DATA - Safe handling
            $cert_count = 0;
            $achieve_count = 0;
            $cert_list = [];
            
            if ( method_exists( $student, 'get_certificates' ) ) {
                $certificates = $student->get_certificates();
                
                if ( is_array( $certificates ) ) {
                    $cert_count = count( $certificates );
                    
                    foreach ( $certificates as $cert ) {
                        if ( ! is_object( $cert ) || ! isset( $cert->certificate_id ) ) {
                            continue;
                        }
                        
                        $cert_post = get_post( $cert->certificate_id );
                        if ( $cert_post && isset( $cert_post->post_title ) ) {
                            $earned_date = 'Unknown';
                            
                            if ( isset( $cert->earned_date ) ) {
                                $earned_date = date( 'M j, Y', strtotime( $cert->earned_date ) );
                            }
                            
                            $cert_list[] = sanitize_text_field( $cert_post->post_title ) . " (Earned: {$earned_date})";
                        }
                    }
                }
            }
            
            if ( method_exists( $student, 'get_achievements' ) ) {
                $achievements = $student->get_achievements();
                $achieve_count = is_array( $achievements ) ? count( $achievements ) : 0;
            }
            
            update_field( 'llms_certificate_count', $cert_count, $post_id );
            update_field( 'llms_achievement_count', $achieve_count, $post_id );
            update_field( 'llms_certificates_list', ! empty( $cert_list ) ? implode( "\n", $cert_list ) : 'No certificates earned', $post_id );
            
        } catch ( Exception $e ) {
            error_log( "LifterLMS sync error for user {$user_id}: " . $e->getMessage() );
            update_field( 'llms_course_details', 'Error loading LifterLMS data: ' . $e->getMessage(), $post_id );
        }
    }
    
    /**
     * ========================================
     * TAB 8: ALL USER META
     * ========================================
     */
    private function update_user_meta_dump( $post_id, $user_id ) {
        try {
            $all_meta = get_user_meta( $user_id );
            $formatted = [];
            
            if ( is_array( $all_meta ) ) {
                foreach ( $all_meta as $key => $values ) {
                    if ( ! is_array( $values ) || empty( $values ) ) {
                        continue;
                    }
                    
                    $value = maybe_unserialize( $values[0] );
                    
                    if ( is_array( $value ) || is_object( $value ) ) {
                        $json = json_encode( $value, JSON_PRETTY_PRINT );
                        if ( $json !== false ) {
                            $formatted[] = sanitize_text_field( $key ) . ': ' . $json;
                        }
                    } else {
                        $formatted[] = sanitize_text_field( $key ) . ': ' . sanitize_text_field( strval( $value ) );
                    }
                    
                    // Limit to prevent memory issues
                    if ( count( $formatted ) > 500 ) {
                        $formatted[] = '... (truncated for performance)';
                        break;
                    }
                }
            }
            
            update_field( 'all_user_meta', implode( "\n", $formatted ), $post_id );
            
        } catch ( Exception $e ) {
            error_log( "User meta dump error: " . $e->getMessage() );
            update_field( 'all_user_meta', 'Error loading user meta', $post_id );
        }
    }
    
    /**
     * ========================================
     * TAB 9: SYNC STATUS
     * ========================================
     */
    private function update_sync_status( $post_id ) {
        update_field( 'whalesync_status', 'active', $post_id );
        update_field( 'last_sync', current_time( 'mysql' ), $post_id );
        update_field( 'sync_errors', '', $post_id );
    }
    
    /**
     * AJAX handler for single user sync
     */
    public function ajax_sync_single_user() {
        check_ajax_referer( 'sync_single_user', 'nonce' );
        
        if ( ! current_user_can( 'manage_options' ) ) {
            wp_die( -1 );
        }
        
        $user_id = isset( $_POST['user_id'] ) ? intval( $_POST['user_id'] ) : 0;
        
        if ( ! $user_id ) {
            wp_send_json_error( 'Invalid user ID' );
        }
        
        $result = $this->sync_single_user( $user_id );
        
        if ( $result ) {
            wp_send_json_success( "User #{$user_id} synced successfully" );
        } else {
            wp_send_json_error( "Failed to sync user #{$user_id}" );
        }
    }
}
// Initialize the sync class
add_action( 'init', function() {
    WPRUS_BB_Manual_Sync::get_instance();
} );
/**
 * ========================================
 * HELPER FUNCTIONS
 * ========================================
 */
function wprus_get_user_sync_post( $user_id ) {
    $posts = get_posts( [
        'post_type'      => 'users_bb_sync',
        'posts_per_page' => 1,
        'post_status'    => 'any',
        'meta_query'     => [
            [
                'key'     => 'user_id',
                'value'   => $user_id,
                'compare' => '=',
                'type'    => 'NUMERIC'
            ]
        ],
        'suppress_filters' => false,
    ] );
    
    return ! empty( $posts ) ? $posts[0] : null;
}
add_shortcode( 'sync_user_button', function( $atts ) {
    $atts = shortcode_atts( [
        'user_id' => get_current_user_id(),
        'text'    => 'Sync My Profile',
    ], $atts );
    
    if ( ! current_user_can( 'manage_options' ) ) {
        return '';
    }
    
    $url = add_query_arg( [
        'sync_users' => '1',
        'user_id'    => $atts['user_id'],
        '_wpnonce'   => wp_create_nonce( 'sync_users_bb' ),
    ], admin_url() );
    
    return sprintf(
        '<a href="%s" class="button sync-user-button">%s</a>',
        esc_url( $url ),
        esc_html( $atts['text'] )
    );
} );
add_action( 'edit_user_profile', function( $user ) {
    if ( ! current_user_can( 'manage_options' ) ) {
        return;
    }
    
    $sync_url = add_query_arg( [
        'sync_users' => '1',
        'user_id'    => $user->ID,
        '_wpnonce'   => wp_create_nonce( 'sync_users_bb' ),
    ], admin_url() );
    ?>
    <h2>User Sync</h2>
    <table class="form-table">
        <tr>
            <th>Manual Sync</th>
            <td>
                <a href="<?php echo esc_url( $sync_url ); ?>" class="button button-primary">
                    Sync This User to Custom Post Type
                </a>
                <p class="description">
                    Manually sync this user's data to the users_bb_sync custom post type.
                </p>
            </td>
        </tr>
    </table>
    <?php
} );

Comments

Add a Comment