BuddyPress Member Export Import – Developer Guide

Architecture Overview

Core Components

bp-xprofile-export-import/
├── bp-xprofile-export-import.php    # Main plugin file
├── includes/
│   ├── class-bp-xprofile-export-import.php         # Core plugin class
│   ├── class-bp-xprofile-export-import-loader.php  # Hook/filter loader
│   ├── class-bp-xprofile-export-import-i18n.php    # Internationalization
│   └── cli/                                        # WP-CLI commands
├── admin/
│   ├── class-bp-xprofile-export-import-admin.php   # Admin interface
│   ├── class-bp-xprofile-admin-export-ajax.php     # Export AJAX handler
│   ├── class-bp-xprofile-admin-import-ajax.php     # Import AJAX handler
│   └── class-bp-groups-export-ajax.php             # Groups export handler
└── edd-license/                                    # License management

Class Hierarchy

Bp_Xprofile_Export_Import (Main Controller)
├── Bp_Xprofile_Export_Import_Loader (Hook Management)
├── Bp_Xprofile_Export_Import_Admin (Admin Interface)
├── Bp_Xprofile_Export_Import_Admin_Export_Ajax (Export Handler)
├── Bp_Xprofile_Export_Import_Admin_Import_Ajax (Import Handler)
├── Bp_Groups_Export_Ajax (Groups Handler)
└── BP_Member_CLI (CLI Commands)

Data Flow

Export Process

  1. User selects members/fields in admin UI
  2. AJAX request to bpxp_export_xprofile_data
  3. Data fetched from database in batches
  4. CSV generated with proper encoding
  5. File sent to browser for download

Import Process

  1. User uploads CSV file
  2. File parsed and headers extracted
  3. User maps CSV columns to xProfile fields
  4. AJAX batch processing of user creation/updates
  5. Progress reported back to UI

Key Files and Their Purposes

Main Plugin File

// bp-xprofile-export-import.php
define('BPXP_PLUGIN_VERSION', '1.6.0');
define('BPXP_PLUGIN_PATH', plugin_dir_path(__FILE__));
define('BPXP_PLUGIN_URL', plugin_dir_url(__FILE__));

Core Plugin Class

// includes/class-bp-xprofile-export-import.php
class Bp_Xprofile_Export_Import {
    protected $loader;
    protected $plugin_name;
    protected $version;

    public function __construct() {
        $this->plugin_name = 'bp-xprofile-export-import';
        $this->version = BPXP_PLUGIN_VERSION;
        $this->load_dependencies();
        $this->set_locale();
        $this->define_admin_hooks();
        $this->define_cli_commands();
    }
}

Action Hooks

Export Page Hooks

// Before/After user selection dropdown
do_action('bpxp_before_export_select_user');
do_action('bpxp_after_export_select_user');

// Before/After field group selection
do_action('bpxp_before_export_fields_group');
do_action('bpxp_after_export_fields_group');

// Before/After individual field selection
do_action('bpxp_before_export_prof_fields');
do_action('bpxp_after_export_prof_fields');

// After export button
do_action('bpxp_after_export_buttons');

Import Page Hooks

// Server limits section
do_action('bpxp_before_import_limit');
do_action('bpxp_after_import_limit');

// File upload section
do_action('bpxp_before_import_file');
do_action('bpxp_after_import_file');

// Update existing users option
do_action('bpxp_before_import_update_user');
do_action('bpxp_after_import_update_user');

// After import button
do_action('bpxp_after_import_button');

Processing Hooks

// Before/After export processing
do_action('bpxp_before_export_process', $user_ids, $fields);
do_action('bpxp_after_export_process', $csv_content, $user_count);

// Before/After import processing
do_action('bpxp_before_import_process', $csv_data, $field_mapping);
do_action('bpxp_after_import_process', $import_results);

// Before/After user creation/update
do_action('bpxp_before_user_import', $user_data, $is_update);
do_action('bpxp_after_user_import', $user_id, $user_data, $is_update);

// Before/After xProfile update
do_action('bpxp_before_xprofile_update', $user_id, $field_id, $value);
do_action('bpxp_after_xprofile_update', $user_id, $field_id, $value);

Filter Hooks

Configuration Filters

// Maximum users to display in dropdown
add_filter('bpxp_max_users_display', function($limit) {
    return 500; // Default: 200
});

// Export batch size
add_filter('bpxp_export_batch_size', function($size, $total_users) {
    if ($total_users > 50000) {
        return 500;
    }
    return 1000; // Default
}, 10, 2);

// Import batch size
add_filter('bpxp_import_batch_size', function($size) {
    return 25; // Default: 10
});

// Memory limit for operations
add_filter('bpxp_memory_limit', function($limit) {
    return '512M'; // Default: 256M
});

Data Processing Filters

// Filter export data before CSV generation
add_filter('bpxp_export_user_data', function($user_data, $user_id) {
    // Modify user data before export
    return $user_data;
}, 10, 2);

// Filter import data before processing
add_filter('bpxp_import_user_data', function($user_data, $csv_row) {
    // Modify user data before import
    return $user_data;
}, 10, 2);

// Filter xProfile field value during export
add_filter('bpxp_export_field_value', function($value, $field_id, $user_id) {
    // Modify field value for export
    return $value;
}, 10, 3);

// Filter xProfile field value during import
add_filter('bpxp_import_field_value', function($value, $field_id, $user_id) {
    // Modify field value before saving
    return $value;
}, 10, 3);

// Filter CSV headers
add_filter('bpxp_csv_headers', function($headers) {
    // Add custom headers
    $headers[] = 'custom_field';
    return $headers;
});

// Filter user meta fields to export
add_filter('bpxp_export_user_meta_fields', function($fields) {
    // Add/remove meta fields
    $fields[] = 'custom_meta_key';
    return $fields;
});

Validation Filters

// Validate user data before import
add_filter('bpxp_validate_user_data', function($is_valid, $user_data) {
    // Custom validation logic
    if (empty($user_data['user_email'])) {
        return false;
    }
    return $is_valid;
}, 10, 2);

// Validate field value
add_filter('bpxp_validate_field_value', function($is_valid, $value, $field) {
    // Custom field validation
    return $is_valid;
}, 10, 3);

AJAX Endpoints

Export Endpoints

Get xProfile Fields

// Action: bpxp_get_export_xprofile_fields
jQuery.ajax({
    url: ajaxurl,
    type: 'POST',
    data: {
        action: 'bpxp_get_export_xprofile_fields',
        group_ids: [1, 2, 3],
        nonce: bpxp_export_object.nonce
    },
    success: function(response) {
        // Handle fields data
    }
});

Export Members

// Action: bpxp_export_xprofile_data
jQuery.ajax({
    url: ajaxurl,
    type: 'POST',
    data: {
        action: 'bpxp_export_xprofile_data',
        user_ids: [1, 2, 3],
        field_ids: [1, 2, 3],
        include_standard: true,
        include_meta: true,
        nonce: bpxp_export_object.nonce
    },
    success: function(response) {
        // Handle CSV download
    }
});

Import Endpoints

Parse CSV Headers

// Action: bpxp_import_header_fields
var formData = new FormData();
formData.append('action', 'bpxp_import_header_fields');
formData.append('csv_file', fileInput.files[0]);
formData.append('nonce', bpxp_import_object.nonce);

jQuery.ajax({
    url: ajaxurl,
    type: 'POST',
    data: formData,
    processData: false,
    contentType: false,
    success: function(response) {
        // Handle header mapping UI
    }
});

Import CSV Data

// Action: bpxp_import_csv_data
jQuery.ajax({
    url: ajaxurl,
    type: 'POST',
    data: {
        action: 'bpxp_import_csv_data',
        csv_data: csvData,
        field_mapping: fieldMapping,
        update_existing: true,
        batch_size: 10,
        offset: 0,
        nonce: bpxp_import_object.nonce
    },
    success: function(response) {
        // Handle import progress
    }
});

Extending the Plugin

Adding Custom Export Fields

// Add custom field to export
add_filter('bpxp_export_user_data', function($user_data, $user_id) {
    // Add custom calculation
    $user_data['total_posts'] = count_user_posts($user_id);

    // Add from custom table
    global $wpdb;
    $custom_value = $wpdb->get_var($wpdb->prepare(
        "SELECT value FROM {$wpdb->prefix}custom_table WHERE user_id = %d",
        $user_id
    ));
    $user_data['custom_value'] = $custom_value;

    return $user_data;
}, 10, 2);

// Add corresponding header
add_filter('bpxp_csv_headers', function($headers) {
    $headers[] = 'total_posts';
    $headers[] = 'custom_value';
    return $headers;
});

Custom Import Processing

// Process custom fields during import
add_action('bpxp_after_user_import', function($user_id, $user_data, $is_update) {
    if (isset($user_data['custom_field'])) {
        update_user_meta($user_id, 'custom_field', $user_data['custom_field']);
    }

    // Trigger custom action
    if (!$is_update) {
        do_action('my_custom_new_user_imported', $user_id, $user_data);
    }
}, 10, 3);

Adding Custom Validation

// Validate email domain
add_filter('bpxp_validate_user_data', function($is_valid, $user_data) {
    if (isset($user_data['user_email'])) {
        $domain = substr(strrchr($user_data['user_email'], "@"), 1);
        $allowed_domains = ['company.com', 'organization.org'];

        if (!in_array($domain, $allowed_domains)) {
            return new WP_Error(
                'invalid_domain',
                'Email domain not allowed: ' . $domain
            );
        }
    }
    return $is_valid;
}, 10, 2);

Custom Field Type Handler

// Register custom field type handler
add_filter('bpxp_field_type_handlers', function($handlers) {
    $handlers['custom_type'] = 'MyCustomFieldHandler';
    return $handlers;
});

class MyCustomFieldHandler {
    public static function export($field_id, $user_id) {
        $value = xprofile_get_field_data($field_id, $user_id);
        // Custom export processing
        return json_encode($value);
    }

    public static function import($field_id, $user_id, $value) {
        // Custom import processing
        $processed_value = json_decode($value, true);
        return xprofile_set_field_data($field_id, $user_id, $processed_value);
    }
}

Custom Field Types

Handling Complex Field Types

Multi-Select Fields

// Export multi-select values
add_filter('bpxp_export_field_value', function($value, $field_id, $user_id) {
    $field = xprofile_get_field($field_id);

    if ($field->type == 'multiselectbox') {
        if (is_array($value)) {
            return implode('|', $value);
        }
    }

    return $value;
}, 10, 3);

// Import multi-select values
add_filter('bpxp_import_field_value', function($value, $field_id, $user_id) {
    $field = xprofile_get_field($field_id);

    if ($field->type == 'multiselectbox') {
        return explode('|', $value);
    }

    return $value;
}, 10, 3);

Date Fields

// Handle date field formats
add_filter('bpxp_export_field_value', function($value, $field_id, $user_id) {
    $field = xprofile_get_field($field_id);

    if ($field->type == 'datebox') {
        // Convert to standard format
        $date = DateTime::createFromFormat('Y-m-d H:i:s', $value);
        if ($date) {
            return $date->format('Y-m-d');
        }
    }

    return $value;
}, 10, 3);

File Upload Fields

// Export file URLs
add_filter('bpxp_export_field_value', function($value, $field_id, $user_id) {
    $field = xprofile_get_field($field_id);

    if ($field->type == 'file') {
        // Convert attachment ID to URL
        if (is_numeric($value)) {
            return wp_get_attachment_url($value);
        }
    }

    return $value;
}, 10, 3);

// Import files from URLs
add_filter('bpxp_import_field_value', function($value, $field_id, $user_id) {
    $field = xprofile_get_field($field_id);

    if ($field->type == 'file' && filter_var($value, FILTER_VALIDATE_URL)) {
        // Download and create attachment
        $attachment_id = bpxp_import_file_from_url($value, $user_id);
        return $attachment_id;
    }

    return $value;
}, 10, 3);

Performance Optimization

Memory Management

// Optimize memory for large exports
add_action('bpxp_before_export_process', function($user_ids, $fields) {
    // Increase memory limit
    ini_set('memory_limit', '512M');

    // Disable query logging
    global $wpdb;
    $wpdb->queries = array();

    // Clear object cache
    wp_cache_flush();
});

// Batch processing optimization
add_filter('bpxp_export_batch_size', function($size, $total_users) {
    $memory_limit = ini_get('memory_limit');
    $memory_bytes = wp_convert_hr_to_bytes($memory_limit);

    // Adjust batch size based on available memory
    if ($memory_bytes < 134217728) { // Less than 128MB
        return 100;
    } elseif ($memory_bytes < 268435456) { // Less than 256MB
        return 500;
    } else {
        return 1000;
    }
}, 10, 2);

Database Optimization

// Optimize queries for large datasets
add_filter('bpxp_user_query_args', function($args) {
    // Add specific fields to reduce memory
    $args['fields'] = ['ID', 'user_login', 'user_email'];

    // Disable meta queries if not needed
    $args['meta_query'] = array();

    return $args;
});

// Use direct database queries for performance
add_action('bpxp_export_direct_query', function($user_ids) {
    global $wpdb;

    $user_ids_str = implode(',', array_map('intval', $user_ids));

    $results = $wpdb->get_results("
        SELECT u.ID, u.user_login, u.user_email,
               GROUP_CONCAT(DISTINCT g.name) as groups
        FROM {$wpdb->users} u
        LEFT JOIN {$wpdb->prefix}bp_groups_members gm ON u.ID = gm.user_id
        LEFT JOIN {$wpdb->prefix}bp_groups g ON gm.group_id = g.id
        WHERE u.ID IN ($user_ids_str)
        GROUP BY u.ID
    ");

    return $results;
});

Caching Strategy

// Cache xProfile field structure
add_filter('bpxp_get_xprofile_fields', function($fields) {
    $cache_key = 'bpxp_xprofile_fields';
    $cached = wp_cache_get($cache_key);

    if ($cached !== false) {
        return $cached;
    }

    // Get fields from database
    $fields = BP_XProfile_Group::get(array(
        'fetch_fields' => true
    ));

    // Cache for 1 hour
    wp_cache_set($cache_key, $fields, '', HOUR_IN_SECONDS);

    return $fields;
});

Security Considerations

Capability Checks

// Add custom capability check
add_filter('bpxp_export_capability', function($capability) {
    // Require higher permission for export
    return 'export_users'; // Default: 'manage_options'
});

add_filter('bpxp_import_capability', function($capability) {
    // Require specific capability for import
    return 'import_users'; // Default: 'manage_options'
});

Data Sanitization

// Sanitize import data
add_filter('bpxp_import_user_data', function($user_data, $csv_row) {
    // Sanitize email
    if (isset($user_data['user_email'])) {
        $user_data['user_email'] = sanitize_email($user_data['user_email']);
    }

    // Sanitize username
    if (isset($user_data['user_login'])) {
        $user_data['user_login'] = sanitize_user($user_data['user_login']);
    }

    // Sanitize HTML content
    if (isset($user_data['description'])) {
        $user_data['description'] = wp_kses_post($user_data['description']);
    }

    return $user_data;
}, 10, 2);

File Upload Validation

// Validate CSV file upload
add_filter('bpxp_validate_csv_file', function($is_valid, $file) {
    // Check file extension
    $allowed_types = ['csv', 'txt'];
    $file_ext = strtolower(pathinfo($file['name'], PATHINFO_EXTENSION));

    if (!in_array($file_ext, $allowed_types)) {
        return new WP_Error('invalid_file_type', 'Only CSV files allowed');
    }

    // Check MIME type
    $finfo = finfo_open(FILEINFO_MIME_TYPE);
    $mime_type = finfo_file($finfo, $file['tmp_name']);
    finfo_close($finfo);

    if (!in_array($mime_type, ['text/csv', 'text/plain'])) {
        return new WP_Error('invalid_mime_type', 'Invalid file type');
    }

    // Check file size (10MB limit)
    if ($file['size'] > 10485760) {
        return new WP_Error('file_too_large', 'File size exceeds 10MB');
    }

    return $is_valid;
}, 10, 2);

Code Examples

Complete Export Integration

/**
 * Custom export integration with additional data
 */
class My_Custom_Export_Integration {

    public function __construct() {
        add_filter('bpxp_export_user_data', [$this, 'add_custom_data'], 10, 2);
        add_filter('bpxp_csv_headers', [$this, 'add_custom_headers']);
        add_action('bpxp_after_export_process', [$this, 'log_export'], 10, 2);
    }

    public function add_custom_data($user_data, $user_id) {
        // Add WooCommerce order count
        if (class_exists('WooCommerce')) {
            $user_data['order_count'] = wc_get_customer_order_count($user_id);
            $user_data['total_spent'] = wc_get_customer_total_spent($user_id);
        }

        // Add forum post count
        if (function_exists('bbp_get_user_post_count')) {
            $user_data['forum_posts'] = bbp_get_user_post_count($user_id);
        }

        // Add custom meta
        $user_data['last_login'] = get_user_meta($user_id, 'last_login', true);

        return $user_data;
    }

    public function add_custom_headers($headers) {
        if (class_exists('WooCommerce')) {
            $headers[] = 'order_count';
            $headers[] = 'total_spent';
        }

        if (function_exists('bbp_get_user_post_count')) {
            $headers[] = 'forum_posts';
        }

        $headers[] = 'last_login';

        return $headers;
    }

    public function log_export($csv_content, $user_count) {
        // Log export activity
        $log_entry = sprintf(
            '[%s] Exported %d users by %s',
            current_time('mysql'),
            $user_count,
            wp_get_current_user()->user_login
        );

        error_log($log_entry, 3, WP_CONTENT_DIR . '/bpxp-export.log');
    }
}

new My_Custom_Export_Integration();

Complete Import Integration

/**
 * Custom import integration with validation and processing
 */
class My_Custom_Import_Integration {

    public function __construct() {
        add_filter('bpxp_validate_user_data', [$this, 'validate_data'], 10, 2);
        add_filter('bpxp_import_user_data', [$this, 'process_data'], 10, 2);
        add_action('bpxp_after_user_import', [$this, 'after_import'], 10, 3);
    }

    public function validate_data($is_valid, $user_data) {
        // Validate email domain
        if (isset($user_data['user_email'])) {
            $domain = substr(strrchr($user_data['user_email'], "@"), 1);

            if ($domain === 'blocked.com') {
                return new WP_Error('blocked_domain', 'This email domain is not allowed');
            }
        }

        // Validate age if present
        if (isset($user_data['age']) && $user_data['age'] < 18) {
            return new WP_Error('underage', 'Users must be 18 or older');
        }

        return $is_valid;
    }

    public function process_data($user_data, $csv_row) {
        // Process phone number format
        if (isset($user_data['phone'])) {
            $user_data['phone'] = preg_replace('/[^0-9]/', '', $user_data['phone']);
        }

        // Set default values
        if (!isset($user_data['role'])) {
            $user_data['role'] = 'subscriber';
        }

        // Generate username from email if not provided
        if (!isset($user_data['user_login']) && isset($user_data['user_email'])) {
            $user_data['user_login'] = strstr($user_data['user_email'], '@', true);
        }

        return $user_data;
    }

    public function after_import($user_id, $user_data, $is_update) {
        // Add to custom group
        if (!$is_update && function_exists('groups_join_group')) {
            groups_join_group(array(
                'group_id' => 1, // New members group
                'user_id' => $user_id
            ));
        }

        // Send custom notification
        if (!$is_update) {
            $this->send_welcome_notification($user_id, $user_data);
        }

        // Log import
        $this->log_import($user_id, $user_data, $is_update);
    }

    private function send_welcome_notification($user_id, $user_data) {
        $subject = 'Welcome to our community!';
        $message = sprintf(
            'Hello %s, welcome to our platform!',
            $user_data['display_name'] ?? $user_data['user_login']
        );

        wp_mail($user_data['user_email'], $subject, $message);
    }

    private function log_import($user_id, $user_data, $is_update) {
        $action = $is_update ? 'updated' : 'created';

        $log_entry = sprintf(
            '[%s] User %s (%d) %s',
            current_time('mysql'),
            $user_data['user_login'],
            $user_id,
            $action
        );

        error_log($log_entry, 3, WP_CONTENT_DIR . '/bpxp-import.log');
    }
}

new My_Custom_Import_Integration();

API Reference

Global Functions

/**
 * Get xProfile fields for export
 * @param array $group_ids Optional group IDs to filter
 * @return array Field data
 */
function bpxp_get_export_fields($group_ids = array()) {
    return apply_filters('bpxp_export_fields', $fields, $group_ids);
}

/**
 * Export users to CSV
 * @param array $user_ids User IDs to export
 * @param array $field_ids Field IDs to include
 * @param array $options Export options
 * @return string CSV content
 */
function bpxp_export_users($user_ids, $field_ids, $options = array()) {
    $defaults = array(
        'include_standard' => true,
        'include_meta' => false,
        'include_avatar' => false,
        'include_groups' => false
    );

    $options = wp_parse_args($options, $defaults);

    // Process export
    return apply_filters('bpxp_export_csv', $csv, $user_ids, $field_ids, $options);
}

/**
 * Import users from CSV data
 * @param array $csv_data Parsed CSV data
 * @param array $field_mapping Column to field mapping
 * @param array $options Import options
 * @return array Import results
 */
function bpxp_import_users($csv_data, $field_mapping, $options = array()) {
    $defaults = array(
        'update_existing' => false,
        'send_notification' => false,
        'default_role' => 'subscriber',
        'batch_size' => 10
    );

    $options = wp_parse_args($options, $defaults);

    // Process import
    return apply_filters('bpxp_import_results', $results, $csv_data, $field_mapping, $options);
}

/**
 * Parse CSV file
 * @param string $file_path Path to CSV file
 * @return array Parsed CSV data
 */
function bpxp_parse_csv($file_path) {
    $csv_data = array();

    if (($handle = fopen($file_path, 'r')) !== false) {
        $headers = fgetcsv($handle);

        while (($row = fgetcsv($handle)) !== false) {
            $csv_data[] = array_combine($headers, $row);
        }

        fclose($handle);
    }

    return apply_filters('bpxp_parsed_csv', $csv_data, $file_path);
}

Class Methods

// Export handler methods
Bp_Xprofile_Export_Import_Admin_Export_Ajax::export_users()
Bp_Xprofile_Export_Import_Admin_Export_Ajax::get_xprofile_fields()
Bp_Xprofile_Export_Import_Admin_Export_Ajax::generate_csv()

// Import handler methods
Bp_Xprofile_Export_Import_Admin_Import_Ajax::import_users()
Bp_Xprofile_Export_Import_Admin_Import_Ajax::parse_csv_headers()
Bp_Xprofile_Export_Import_Admin_Import_Ajax::process_batch()

// Utility methods
Bp_Xprofile_Export_Import::get_user_meta_fields()
Bp_Xprofile_Export_Import::sanitize_field_value()
Bp_Xprofile_Export_Import::validate_csv_data()

Support

For developer support:

  1. GitHub Issues: github.com/wbcomdesigns
  2. Support Forum: wbcomdesigns.com/support
Last updated: September 30, 2025