BuddyPress Activity Share Pro – Complete Developer Guide

Get Started

Architecture Overview

Plugin Structure

buddypress-activity-share-pro/
├── admin/                    # Admin functionality
│   ├── class-buddypress-share-admin.php
│   ├── css/                 # Admin styles
│   └── js/                  # Admin scripts
├── public/                  # Frontend functionality
│   ├── class-buddypress-share-public.php
│   ├── css/                 # Frontend styles
│   └── js/                  # Frontend scripts
├── includes/                # Core functionality
│   ├── class-buddypress-share.php
│   ├── class-buddypress-share-tracker.php
│   ├── class-buddypress-share-assets.php
│   └── bp-share-helpers.php
└── buddypress-share.php    # Main plugin file

Loading Sequence

1. buddypress-share.php          // Entry point
2. class-buddypress-share.php    // Core initialization
3. class-buddypress-share-loader.php  // Hook registration
4. class-buddypress-share-public.php  // Frontend features
5. class-buddypress-share-admin.php   // Admin features

Core Classes & Methods

Main Plugin Class

class Buddypress_Share {
    
    /**
     * Initialize the plugin
     */
    public function __construct() {
        $this->load_dependencies();
        $this->set_locale();
        $this->define_admin_hooks();
        $this->define_public_hooks();
    }
    
    /**
     * Run the plugin
     */
    public function run() {
        $this->loader->run();
    }
}

Public Class Methods

class Buddypress_Share_Public {
    
    /**
     * Add share buttons to activity
     * 
     * @param string $content Activity content
     * @return string Modified content with share buttons
     */
    public function bp_activity_share_button_display_handler($content) {
        if (!$this->should_display_buttons()) {
            return $content;
        }
        
        $buttons = $this->generate_share_buttons();
        return $content . $buttons;
    }
    
    /**
     * Generate share buttons HTML
     * 
     * @param int $activity_id Activity ID
     * @return string HTML output
     */
    public function generate_share_buttons($activity_id = null) {
        $services = $this->get_enabled_services();
        $html = '<div class="bp-share-buttons">';
        
        foreach ($services as $service => $config) {
            $html .= $this->generate_button($service, $config, $activity_id);
        }
        
        $html .= '</div>';
        return apply_filters('bp_share_buttons_html', $html, $activity_id);
    }
}

Tracker Class

class Buddypress_Share_Tracker {
    
    /**
     * Track internal share event
     * 
     * @param int $user_id User who shared
     * @param string $reshare_type Type of reshare
     * @param int $original_activity Original activity ID
     * @param int $new_activity_id New activity ID
     */
    public function track_internal_share($user_id, $reshare_type, $original_activity, $new_activity_id) {
        $share_data = array(
            'user_id' => $user_id,
            'activity_id' => $original_activity,
            'new_activity_id' => $new_activity_id,
            'share_type' => 'internal',
            'destination_type' => $reshare_type,
            'timestamp' => current_time('mysql'),
            'ip_address' => $this->get_user_ip()
        );
        
        // Store in database or trigger action
        do_action('bp_share_internal_tracked', $share_data);
        
        // Update statistics
        $this->update_share_statistics($share_data);
    }
    
    /**
     * Get share statistics
     * 
     * @param int $activity_id Activity ID
     * @return array Statistics data
     */
    public function get_share_statistics($activity_id) {
        $stats = array(
            'total_shares' => $this->get_total_shares($activity_id),
            'platform_breakdown' => $this->get_platform_breakdown($activity_id),
            'time_distribution' => $this->get_time_distribution($activity_id),
            'user_stats' => $this->get_user_statistics($activity_id)
        );
        
        return apply_filters('bp_share_statistics', $stats, $activity_id);
    }
}

Hooks Reference

Action Hooks

bp_share_before_buttons

Fires before share buttons are displayed.

do_action('bp_share_before_buttons', $activity_id);

// Example usage
add_action('bp_share_before_buttons', function($activity_id) {
    echo '<div class="share-header">Share this post:</div>';
});

bp_share_after_buttons

Fires after share buttons are displayed.

do_action('bp_share_after_buttons', $activity_id);

// Example usage
add_action('bp_share_after_buttons', function($activity_id) {
    $count = bp_share_get_total_shares($activity_id);
    echo "<span class='share-count'>Shared {$count} times</span>";
});

bp_share_user_reshared_activity

Fires when a user reshares an activity.

do_action('bp_share_user_reshared_activity', 
    $user_id,           // User who shared
    $reshare_type,      // 'profile', 'group', or 'message'
    $original_activity, // Original activity ID
    $new_activity_id    // New activity ID created
);

// Example: Award points
add_action('bp_share_user_reshared_activity', function($user_id, $type, $original, $new) {
    if (function_exists('mycred_add')) {
        mycred_add('activity_reshare', $user_id, 10, 'Reshared activity %d', $original);
    }
}, 10, 4);

bp_share_external_share_tracked

Fires when an external share is tracked.

do_action('bp_share_external_share_tracked', $share_data);

// Share data structure
$share_data = array(
    'activity_id' => 123,
    'user_id' => 456,
    'service' => 'facebook',
    'timestamp' => '2024-01-01 12:00:00',
    'ip_address' => '192.168.1.1'
);

bp_share_settings_saved

Fires after settings are saved.

do_action('bp_share_settings_saved', $settings);

// Example: Clear cache after settings change
add_action('bp_share_settings_saved', function($settings) {
    wp_cache_delete('bp_share_settings', 'bp_share');
    wp_cache_delete('bp_share_services', 'bp_share');
});

More Action Hooks

// Activity-specific hooks
do_action('bp_share_activity_shared', $activity_id, $platform);
do_action('bp_share_before_reshare_content', $activity_id);
do_action('bp_share_after_reshare_created', $new_activity_id);

// Admin hooks
do_action('bp_share_admin_settings_init');
do_action('bp_share_admin_enqueue_scripts');

// Tracking hooks
do_action('bp_share_visit_tracked', $activity_id, $referrer);
do_action('bp_share_analytics_updated', $stats_data);

Filters Reference

Service Filters

bp_share_services

Modify available social services.

add_filter('bp_share_services', function($services) {
    // Add custom service
    $services['discord'] = array(
        'name' => 'Discord',
        'icon' => 'fab fa-discord',
        'url' => 'https://discord.com/share?url={url}&text={title}',
        'color' => '#7289da'
    );
    
    // Remove a service
    unset($services['pinterest']);
    
    return $services;
});

bp_share_enabled_services

Filter which services are enabled.

add_filter('bp_share_enabled_services', function($enabled) {
    // Only enable specific services for mobile
    if (wp_is_mobile()) {
        return array('whatsapp', 'telegram', 'facebook');
    }
    return $enabled;
});

Display Filters

bp_share_display_conditions

Control when share buttons are displayed.

add_filter('bp_share_display_conditions', function($display, $activity) {
    // Don't show for activities older than 30 days
    $activity_date = strtotime($activity->date_recorded);
    $days_old = (time() - $activity_date) / (60 * 60 * 24);
    
    if ($days_old > 30) {
        return false;
    }
    
    // Don't show for private activities
    if ($activity->hide_sitewide) {
        return false;
    }
    
    return $display;
}, 10, 2);

bp_share_button_html

Modify individual button HTML.

add_filter('bp_share_button_html', function($html, $service, $activity_id) {
    // Add custom attributes
    $html = str_replace('<a ', '<a data-service="' . $service . '" ', $html);
    
    // Add share count
    $count = bp_share_get_service_count($activity_id, $service);
    if ($count > 0) {
        $html .= "<span class='share-count'>{$count}</span>";
    }
    
    return $html;
}, 10, 3);

Content Filters

bp_share_activity_content

Modify shared activity content.

add_filter('bp_share_activity_content', function($content, $activity) {
    // Add watermark to reshared content
    $content .= "\n\n— Shared via " . get_bloginfo('name');
    
    // Limit content length
    if (strlen($content) > 500) {
        $content = substr($content, 0, 497) . '...';
    }
    
    return $content;
}, 10, 2);

bp_share_tracking_parameters

Modify tracking parameters.

add_filter('bp_share_tracking_parameters', function($params, $activity_id, $service) {
    // Add custom tracking parameters
    $params['campaign_id'] = 'summer_2024';
    $params['user_type'] = is_user_logged_in() ? 'member' : 'visitor';
    $params['activity_type'] = bp_activity_get_meta($activity_id, 'activity_type', true);
    
    // Add A/B testing parameter
    $params['variant'] = (rand(0, 1) == 0) ? 'a' : 'b';
    
    return $params;
}, 10, 3);

More Filters

// Customization filters
apply_filters('bp_share_button_classes', $classes, $service);
apply_filters('bp_share_button_text', $text, $service);
apply_filters('bp_share_icon_class', $icon_class, $service);

// Permission filters
apply_filters('bp_share_user_can_share', $can_share, $user_id, $activity_id);
apply_filters('bp_share_activity_shareable', $shareable, $activity);

// URL filters
apply_filters('bp_share_activity_url', $url, $activity_id);
apply_filters('bp_share_permalink', $permalink, $activity);

// Analytics filters
apply_filters('bp_share_analytics_data', $data, $activity_id);
apply_filters('bp_share_statistics_query', $query, $args);

JavaScript API

Core Functions

// BPShare namespace
window.BPShare = {
    
    /**
     * Initialize share functionality
     */
    init: function() {
        this.bindEvents();
        this.setupTracking();
    },
    
    /**
     * Share to external platform
     */
    shareExternal: function(platform, activityId) {
        const url = this.getShareUrl(platform, activityId);
        
        // Track share event
        this.trackShare(platform, activityId);
        
        // Open share window
        window.open(url, 'share-' + platform, 'width=600,height=400');
    },
    
    /**
     * Share internally
     */
    shareInternal: function(type, activityId) {
        const data = {
            action: 'bp_share_internal',
            type: type,
            activity_id: activityId,
            nonce: bp_share_vars.nonce
        };
        
        jQuery.post(bp_share_vars.ajax_url, data, function(response) {
            if (response.success) {
                BPShare.showNotification('Activity shared successfully!');
                BPShare.updateShareCount(activityId);
            }
        });
    },
    
    /**
     * Track share event
     */
    trackShare: function(platform, activityId) {
        // Google Analytics
        if (typeof gtag !== 'undefined') {
            gtag('event', 'share', {
                'event_category': 'social',
                'event_label': platform,
                'value': activityId
            });
        }
        
        // Custom tracking
        jQuery.post(bp_share_vars.ajax_url, {
            action: 'bp_share_track',
            platform: platform,
            activity_id: activityId,
            nonce: bp_share_vars.nonce
        });
    }
};

// jQuery extensions
jQuery.fn.bpShare = function(options) {
    const settings = jQuery.extend({
        platforms: ['facebook', 'twitter', 'whatsapp'],
        trackingEnabled: true,
        popupWindow: true,
        onShare: function() {},
        onError: function() {}
    }, options);
    
    return this.each(function() {
        // Initialize share buttons
        jQuery(this).on('click', '.bp-share-button', function(e) {
            e.preventDefault();
            
            const platform = jQuery(this).data('service');
            const activityId = jQuery(this).data('activity-id');
            
            try {
                BPShare.shareExternal(platform, activityId);
                settings.onShare(platform, activityId);
            } catch(error) {
                settings.onError(error);
            }
        });
    });
};

Event Listeners

// Document ready
jQuery(document).ready(function($) {
    
    // Initialize share buttons
    $('.bp-share-buttons').bpShare({
        onShare: function(platform, activityId) {
            console.log('Shared to ' + platform);
        }
    });
    
    // Custom share button handler
    $(document).on('click', '.custom-share-btn', function(e) {
        e.preventDefault();
        
        const activityId = $(this).closest('.activity-item').data('id');
        BPShare.openShareModal(activityId);
    });
    
    // Copy link functionality
    $(document).on('click', '.bp-share-copy-link', function(e) {
        e.preventDefault();
        
        const url = $(this).data('url');
        BPShare.copyToClipboard(url);
    });
});

// Custom events
jQuery(document).on('bp_share_completed', function(e, data) {
    console.log('Share completed:', data);
});

jQuery(document).on('bp_share_failed', function(e, error) {
    console.error('Share failed:', error);
});

REST API Endpoints

Available Endpoints

// Get share statistics
GET /wp-json/bp-share/v1/statistics/{activity_id}

// Track external share
POST /wp-json/bp-share/v1/track
{
    "activity_id": 123,
    "service": "facebook",
    "user_id": 456
}

// Create internal share
POST /wp-json/bp-share/v1/reshare
{
    "activity_id": 123,
    "type": "profile",
    "message": "Check this out!"
}

// Get enabled services
GET /wp-json/bp-share/v1/services

// Get user share history
GET /wp-json/bp-share/v1/users/{user_id}/shares

Registering Custom Endpoints

add_action('rest_api_init', function() {
    register_rest_route('bp-share/v1', '/custom-endpoint', array(
        'methods' => 'GET',
        'callback' => 'bp_share_custom_endpoint_handler',
        'permission_callback' => function() {
            return current_user_can('read');
        },
        'args' => array(
            'activity_id' => array(
                'required' => true,
                'validate_callback' => function($param) {
                    return is_numeric($param);
                }
            )
        )
    ));
});

function bp_share_custom_endpoint_handler($request) {
    $activity_id = $request->get_param('activity_id');
    
    // Your custom logic
    $data = array(
        'activity_id' => $activity_id,
        'custom_data' => 'Your data here'
    );
    
    return new WP_REST_Response($data, 200);
}

Database Schema

Custom Tables (Optional)

-- Share tracking table
CREATE TABLE IF NOT EXISTS `{$wpdb->prefix}bp_share_tracking` (
    `id` bigint(20) NOT NULL AUTO_INCREMENT,
    `activity_id` bigint(20) NOT NULL,
    `user_id` bigint(20) DEFAULT NULL,
    `service` varchar(50) NOT NULL,
    `share_type` enum('internal','external') DEFAULT 'external',
    `ip_address` varchar(45) DEFAULT NULL,
    `user_agent` text,
    `referrer` text,
    `timestamp` datetime DEFAULT CURRENT_TIMESTAMP,
    PRIMARY KEY (`id`),
    KEY `activity_id` (`activity_id`),
    KEY `user_id` (`user_id`),
    KEY `service` (`service`),
    KEY `timestamp` (`timestamp`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

-- Share statistics table
CREATE TABLE IF NOT EXISTS `{$wpdb->prefix}bp_share_statistics` (
    `id` bigint(20) NOT NULL AUTO_INCREMENT,
    `activity_id` bigint(20) NOT NULL,
    `service` varchar(50) NOT NULL,
    `share_count` int(11) DEFAULT 0,
    `last_shared` datetime DEFAULT NULL,
    PRIMARY KEY (`id`),
    UNIQUE KEY `activity_service` (`activity_id`, `service`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

Meta Data Storage

// Activity meta
bp_activity_add_meta($activity_id, 'total_shares', 0);
bp_activity_add_meta($activity_id, 'share_services', serialize($services));
bp_activity_add_meta($activity_id, 'last_shared', current_time('mysql'));

// User meta
update_user_meta($user_id, 'bp_share_total_shares', $count);
update_user_meta($user_id, 'bp_share_points', $points);
update_user_meta($user_id, 'bp_share_preferences', $preferences);

Integration Examples

myCRED Integration

/**
 * Award points for sharing activities
 */
add_action('bp_share_user_reshared_activity', function($user_id, $type, $original, $new) {
    if (!function_exists('mycred_add')) {
        return;
    }
    
    // Different points for different share types
    $points = array(
        'profile' => 5,
        'group' => 7,
        'message' => 3
    );
    
    $amount = isset($points[$type]) ? $points[$type] : 5;
    
    // Award points to sharer
    mycred_add(
        'bp_activity_share',
        $user_id,
        $amount,
        'Shared activity to %s',
        $original,
        array('type' => $type),
        'mycred_default'
    );
    
    // Award points to original author
    $activity = bp_activity_get_specific(array('activity_ids' => $original));
    if (!empty($activity['activities'])) {
        $author_id = $activity['activities'][0]->user_id;
        
        mycred_add(
            'bp_activity_reshared',
            $author_id,
            10,
            'Your activity was reshared',
            $original,
            array('sharer' => $user_id),
            'mycred_default'
        );
    }
}, 10, 4);

GamiPress Integration

/**
 * Register GamiPress triggers
 */
add_action('init', function() {
    if (!function_exists('gamipress_register_trigger')) {
        return;
    }
    
    gamipress_register_trigger('bp_share_activity', array(
        'label' => 'Share a BuddyPress activity',
        'listener' => 'bp_share_user_reshared_activity',
        'score' => 10
    ));
    
    gamipress_register_trigger('bp_get_reshared', array(
        'label' => 'Get your activity reshared',
        'listener' => 'bp_share_activity_reshared_by_others',
        'score' => 20
    ));
});

// Trigger when activity is reshared
add_action('bp_share_user_reshared_activity', function($user_id, $type) {
    do_action('gamipress_bp_share_activity', $user_id, $type);
}, 10, 2);

WooCommerce Integration

/**
 * Add share buttons to WooCommerce product activities
 */
add_filter('bp_share_display_conditions', function($display, $activity) {
    // Check if this is a WooCommerce product activity
    if ($activity->type === 'new_product' || $activity->type === 'product_review') {
        return true;
    }
    
    return $display;
}, 10, 2);

// Customize share content for products
add_filter('bp_share_activity_content', function($content, $activity) {
    if ($activity->type === 'new_product') {
        $product_id = bp_activity_get_meta($activity->id, 'product_id', true);
        if ($product_id) {
            $product = wc_get_product($product_id);
            $content = sprintf(
                "Check out %s - Now only %s! %s",
                $product->get_name(),
                $product->get_price_html(),
                $content
            );
        }
    }
    
    return $content;
}, 10, 2);

Custom Analytics Integration

/**
 * Send share data to custom analytics platform
 */
add_action('bp_share_external_share_tracked', function($share_data) {
    // Send to your analytics API
    $api_data = array(
        'event' => 'social_share',
        'properties' => array(
            'activity_id' => $share_data['activity_id'],
            'platform' => $share_data['service'],
            'user_id' => $share_data['user_id'],
            'timestamp' => $share_data['timestamp']
        )
    );
    
    wp_remote_post('https://your-analytics.com/track', array(
        'body' => json_encode($api_data),
        'headers' => array(
            'Content-Type' => 'application/json',
            'Authorization' => 'Bearer YOUR_API_KEY'
        )
    ));
});

Custom Platform Development

Adding a Custom Social Platform

/**
 * Register custom social platform
 */
class BP_Share_Custom_Platform {
    
    public function __construct() {
        add_filter('bp_share_services', array($this, 'register_platform'));
        add_filter('bp_share_platform_share_url', array($this, 'build_share_url'), 10, 3);
        add_action('wp_ajax_bp_share_custom_platform', array($this, 'handle_share'));
    }
    
    public function register_platform($services) {
        $services['custom_platform'] = array(
            'name' => 'Custom Platform',
            'icon' => 'fas fa-share-custom',
            'color' => '#123456',
            'requires_api' => true,
            'api_endpoint' => 'https://api.custom-platform.com/share',
            'api_key' => get_option('custom_platform_api_key')
        );
        
        return $services;
    }
    
    public function build_share_url($url, $platform, $activity) {
        if ($platform !== 'custom_platform') {
            return $url;
        }
        
        $params = array(
            'url' => bp_activity_get_permalink($activity->id),
            'title' => strip_tags($activity->content),
            'api_key' => $this->get_api_key(),
            'user_id' => get_current_user_id()
        );
        
        return add_query_arg($params, 'https://custom-platform.com/share');
    }
    
    public function handle_share() {
        check_ajax_referer('bp_share_nonce', 'nonce');
        
        $activity_id = intval($_POST['activity_id']);
        
        // Custom share logic
        $result = $this->share_to_platform($activity_id);
        
        if ($result) {
            // Track the share
            do_action('bp_share_custom_platform_shared', $activity_id);
            
            wp_send_json_success(array(
                'message' => 'Shared successfully!',
                'share_id' => $result
            ));
        } else {
            wp_send_json_error('Failed to share');
        }
    }
    
    private function share_to_platform($activity_id) {
        // Your API integration logic
        return true;
    }
}

new BP_Share_Custom_Platform();

Performance Optimization

Caching Strategies

/**
 * Implement caching for share counts
 */
class BP_Share_Cache {
    
    const CACHE_GROUP = 'bp_share';
    const CACHE_TIME = 3600; // 1 hour
    
    public static function get_share_count($activity_id) {
        $cache_key = 'share_count_' . $activity_id;
        $count = wp_cache_get($cache_key, self::CACHE_GROUP);
        
        if (false === $count) {
            // Calculate count from database
            $count = self::calculate_share_count($activity_id);
            
            // Store in cache
            wp_cache_set($cache_key, $count, self::CACHE_GROUP, self::CACHE_TIME);
        }
        
        return $count;
    }
    
    public static function invalidate_cache($activity_id) {
        $cache_key = 'share_count_' . $activity_id;
        wp_cache_delete($cache_key, self::CACHE_GROUP);
        
        // Also clear related caches
        wp_cache_delete('popular_shares', self::CACHE_GROUP);
        wp_cache_delete('user_shares_' . get_current_user_id(), self::CACHE_GROUP);
    }
    
    private static function calculate_share_count($activity_id) {
        global $wpdb;
        
        // Get from meta
        $internal = bp_activity_get_meta($activity_id, 'internal_shares', true);
        
        // Get from tracking table if exists
        $external = $wpdb->get_var($wpdb->prepare(
            "SELECT COUNT(*) FROM {$wpdb->prefix}bp_share_tracking 
             WHERE activity_id = %d",
            $activity_id
        ));
        
        return intval($internal) + intval($external);
    }
}

// Use transients for expensive operations
function bp_share_get_popular_activities($limit = 10) {
    $transient_key = 'bp_share_popular_' . $limit;
    $popular = get_transient($transient_key);
    
    if (false === $popular) {
        global $wpdb;
        
        $popular = $wpdb->get_results($wpdb->prepare(
            "SELECT activity_id, COUNT(*) as share_count 
             FROM {$wpdb->prefix}bp_share_tracking 
             GROUP BY activity_id 
             ORDER BY share_count DESC 
             LIMIT %d",
            $limit
        ));
        
        set_transient($transient_key, $popular, HOUR_IN_SECONDS);
    }
    
    return $popular;
}

Database Optimization

/**
 * Optimize database queries
 */

// Add indexes for better performance
function bp_share_create_indexes() {
    global $wpdb;
    
    $indexes = array(
        "ALTER TABLE {$wpdb->prefix}bp_activity_meta 
         ADD INDEX idx_share_meta (meta_key(20), meta_value(50))",
         
        "ALTER TABLE {$wpdb->prefix}bp_share_tracking 
         ADD INDEX idx_user_activity (user_id, activity_id)",
         
        "ALTER TABLE {$wpdb->prefix}bp_share_tracking 
         ADD INDEX idx_service_date (service, timestamp)"
    );
    
    foreach ($indexes as $index) {
        $wpdb->query($index);
    }
}

// Batch processing for large operations
function bp_share_batch_update_statistics() {
    global $wpdb;
    
    $batch_size = 100;
    $offset = 0;
    
    do {
        $activities = $wpdb->get_results($wpdb->prepare(
            "SELECT activity_id, COUNT(*) as count 
             FROM {$wpdb->prefix}bp_share_tracking 
             GROUP BY activity_id 
             LIMIT %d OFFSET %d",
            $batch_size,
            $offset
        ));
        
        foreach ($activities as $activity) {
            bp_activity_update_meta(
                $activity->activity_id,
                'total_external_shares',
                $activity->count
            );
        }
        
        $offset += $batch_size;
        
        // Prevent timeout
        if ($offset % 500 === 0) {
            sleep(1);
        }
        
    } while (count($activities) === $batch_size);
}

Asset Loading Optimization

/**
 * Lazy load share functionality
 */
add_action('wp_enqueue_scripts', function() {
    // Only load on pages with activities
    if (!bp_is_activity_component() && !bp_is_group() && !bp_is_user()) {
        return;
    }
    
    // Load core script with defer
    wp_enqueue_script(
        'bp-share-lazy',
        BP_SHARE_URL . 'assets/js/lazy-share.js',
        array('jquery'),
        BP_SHARE_VERSION,
        true
    );
    
    // Inline critical CSS
    $critical_css = '.bp-share-buttons{display:flex;gap:10px;}';
    wp_add_inline_style('bp-share-main', $critical_css);
    
    // Defer non-critical CSS
    add_filter('style_loader_tag', function($html, $handle) {
        if ('bp-share-icons' === $handle) {
            return str_replace("rel='stylesheet'", "rel='preload' as='style' onload=\"this.rel='stylesheet'\"", $html);
        }
        return $html;
    }, 10, 2);
});

Security Best Practices

Input Sanitization

/**
 * Sanitize all user inputs
 */
class BP_Share_Security {
    
    public static function sanitize_share_data($data) {
        $sanitized = array();
        
        // Sanitize activity ID
        $sanitized['activity_id'] = absint($data['activity_id']);
        
        // Sanitize share type
        $allowed_types = array('profile', 'group', 'message');
        $sanitized['type'] = in_array($data['type'], $allowed_types) 
            ? sanitize_key($data['type']) 
            : 'profile';
        
        // Sanitize message
        $sanitized['message'] = wp_kses_post($data['message']);
        
        // Sanitize service name
        $sanitized['service'] = sanitize_key($data['service']);
        
        return $sanitized;
    }
    
    public static function verify_share_permission($user_id, $activity_id) {
        // Check if user is logged in
        if (!is_user_logged_in()) {
            return false;
        }
        
        // Check if activity exists
        $activity = bp_activity_get_specific(array('activity_ids' => $activity_id));
        if (empty($activity['activities'])) {
            return false;
        }
        
        $activity = $activity['activities'][0];
        
        // Check privacy
        if ($activity->hide_sitewide && $activity->user_id !== $user_id) {
            return false;
        }
        
        // Check user capabilities
        if (!bp_activity_user_can_read($activity, $user_id)) {
            return false;
        }
        
        // Allow filtering
        return apply_filters('bp_share_user_can_share', true, $user_id, $activity);
    }
}

// Nonce verification for AJAX requests
add_action('wp_ajax_bp_share_activity', function() {
    // Verify nonce
    if (!wp_verify_nonce($_POST['nonce'], 'bp_share_nonce')) {
        wp_die('Security check failed');
    }
    
    // Verify user permission
    if (!BP_Share_Security::verify_share_permission(
        get_current_user_id(),
        $_POST['activity_id']
    )) {
        wp_die('Permission denied');
    }
    
    // Sanitize data
    $data = BP_Share_Security::sanitize_share_data($_POST);
    
    // Process share
    bp_share_process($data);
});

Data Validation

/**
 * Validate share data before processing
 */
function bp_share_validate_data($data) {
    $errors = array();
    
    // Validate activity ID
    if (empty($data['activity_id']) || !is_numeric($data['activity_id'])) {
        $errors[] = 'Invalid activity ID';
    }
    
    // Validate URL
    if (!empty($data['url']) && !filter_var($data['url'], FILTER_VALIDATE_URL)) {
        $errors[] = 'Invalid URL';
    }
    
    // Validate service
    $valid_services = bp_share_get_services();
    if (!isset($valid_services[$data['service']])) {
        $errors[] = 'Invalid service';
    }
    
    // Rate limiting
    if (bp_share_is_rate_limited(get_current_user_id())) {
        $errors[] = 'Too many shares. Please wait.';
    }
    
    if (!empty($errors)) {
        return new WP_Error('validation_failed', implode(', ', $errors));
    }
    
    return true;
}

// Rate limiting implementation
function bp_share_is_rate_limited($user_id) {
    $transient_key = 'bp_share_rate_' . $user_id;
    $shares = get_transient($transient_key);
    
    if ($shares >= 10) { // Max 10 shares per minute
        return true;
    }
    
    set_transient($transient_key, $shares + 1, 60);
    return false;
}

Testing & Debugging

Unit Tests

/**
 * PHPUnit test examples
 */
class BP_Share_Test extends WP_UnitTestCase {
    
    public function setUp() {
        parent::setUp();
        
        // Create test user
        $this->user_id = $this->factory->user->create();
        wp_set_current_user($this->user_id);
        
        // Create test activity
        $this->activity_id = bp_activity_add(array(
            'user_id' => $this->user_id,
            'content' => 'Test activity content',
            'type' => 'activity_update'
        ));
    }
    
    public function test_share_button_display() {
        $buttons = bp_share_get_buttons($this->activity_id);
        
        $this->assertNotEmpty($buttons);
        $this->assertContains('bp-share-buttons', $buttons);
    }
    
    public function test_internal_share() {
        $result = bp_share_internal(array(
            'activity_id' => $this->activity_id,
            'type' => 'profile',
            'user_id' => $this->user_id
        ));
        
        $this->assertTrue($result);
        $this->assertEquals(1, bp_share_get_count($this->activity_id));
    }
    
    public function test_tracking_parameters() {
        $params = apply_filters('bp_share_tracking_parameters', array(), $this->activity_id, 'facebook');
        
        $this->assertArrayHasKey('utm_source', $params);
        $this->assertArrayHasKey('utm_medium', $params);
        $this->assertEquals('buddypress_share', $params['utm_source']);
    }
    
    public function test_share_permissions() {
        // Test logged out user
        wp_set_current_user(0);
        $this->assertFalse(bp_share_user_can_share(0, $this->activity_id));
        
        // Test logged in user
        wp_set_current_user($this->user_id);
        $this->assertTrue(bp_share_user_can_share($this->user_id, $this->activity_id));
    }
}

Debug Logging

/**
 * Enable debug logging
 */
if (!defined('BP_SHARE_DEBUG')) {
    define('BP_SHARE_DEBUG', true);
}

function bp_share_log($message, $data = null) {
    if (!BP_SHARE_DEBUG) {
        return;
    }
    
    $log_file = WP_CONTENT_DIR . '/bp-share-debug.log';
    
    $entry = sprintf(
        "[%s] %s\n",
        current_time('mysql'),
        $message
    );
    
    if ($data !== null) {
        $entry .= print_r($data, true) . "\n";
    }
    
    error_log($entry, 3, $log_file);
}

// Usage examples
bp_share_log('Share button clicked', array(
    'activity_id' => $activity_id,
    'service' => $service,
    'user_id' => get_current_user_id()
));

// Debug mode for JavaScript
add_action('wp_enqueue_scripts', function() {
    if (BP_SHARE_DEBUG) {
        wp_localize_script('bp-share-main', 'bp_share_debug', array(
            'enabled' => true,
            'log_level' => 'verbose'
        ));
    }
});

Browser Console Debugging

// Enable debug mode in JavaScript
if (bp_share_debug && bp_share_debug.enabled) {
    
    window.BPShareDebug = {
        log: function(message, data) {
            if (bp_share_debug.log_level === 'verbose') {
                console.group('BP Share Debug');
                console.log(message);
                if (data) {
                    console.table(data);
                }
                console.groupEnd();
            }
        },
        
        trackEvent: function(event, data) {
            this.log('Event: ' + event, data);
            
            // Send to server for logging
            jQuery.post(ajaxurl, {
                action: 'bp_share_log_event',
                event: event,
                data: JSON.stringify(data),
                nonce: bp_share_vars.nonce
            });
        }
    };
    
    // Override share function for debugging
    const originalShare = BPShare.shareExternal;
    BPShare.shareExternal = function(platform, activityId) {
        BPShareDebug.trackEvent('share_attempt', {
            platform: platform,
            activity_id: activityId,
            timestamp: Date.now()
        });
        
        return originalShare.apply(this, arguments);
    };
}

Advanced Features

A/B Testing Implementation

/**
 * Implement A/B testing for share buttons
 */
class BP_Share_AB_Testing {
    
    public static function get_variant($user_id = null) {
        if (!$user_id) {
            $user_id = get_current_user_id();
        }
        
        // Consistent variant for each user
        $variant = get_user_meta($user_id, 'bp_share_ab_variant', true);
        
        if (!$variant) {
            $variant = (rand(0, 1) === 0) ? 'control' : 'variant';
            update_user_meta($user_id, 'bp_share_ab_variant', $variant);
        }
        
        return $variant;
    }
    
    public static function render_buttons($activity_id) {
        $variant = self::get_variant();
        
        if ($variant === 'control') {
            // Original button style
            return bp_share_get_default_buttons($activity_id);
        } else {
            // Variant with different style/position
            return bp_share_get_variant_buttons($activity_id);
        }
    }
    
    public static function track_conversion($variant, $platform) {
        // Track which variant performs better
        $conversions = get_option('bp_share_ab_conversions', array());
        
        if (!isset($conversions[$variant])) {
            $conversions[$variant] = array();
        }
        
        if (!isset($conversions[$variant][$platform])) {
            $conversions[$variant][$platform] = 0;
        }
        
        $conversions[$variant][$platform]++;
        
        update_option('bp_share_ab_conversions', $conversions);
    }
}

Machine Learning Integration

/**
 * Predict share likelihood using ML
 */
class BP_Share_ML_Predictor {
    
    public static function predict_share_probability($activity_id, $user_id) {
        // Collect features
        $features = array(
            'activity_age' => self::get_activity_age($activity_id),
            'content_length' => self::get_content_length($activity_id),
            'has_media' => self::has_media($activity_id),
            'author_popularity' => self::get_author_popularity($activity_id),
            'time_of_day' => date('G'),
            'day_of_week' => date('w'),
            'user_share_history' => self::get_user_share_rate($user_id)
        );
        
        // Send to ML API
        $response = wp_remote_post('https://ml-api.example.com/predict', array(
            'body' => json_encode($features),
            'headers' => array('Content-Type' => 'application/json')
        ));
        
        if (!is_wp_error($response)) {
            $body = json_decode(wp_remote_retrieve_body($response), true);
            return $body['probability'];
        }
        
        return 0.5; // Default probability
    }
    
    public static function should_promote_activity($activity_id) {
        $probability = self::predict_share_probability($activity_id, get_current_user_id());
        
        // Promote activities with high share probability
        return $probability > 0.7;
    }
}

Conclusion

 

This comprehensive developer guide covers all aspects of BuddyPress Activity Share Pro development. Use these examples and references to:

  • Extend functionality with custom features
  • Integrate with third-party services
  • Optimize performance
  • Implement advanced tracking
  • Create custom share platforms
  • Debug and test effectively

For additional support:

Last updated: August 6, 2025