Skip to content

Instantly share code, notes, and snippets.

@goranefbl
Last active October 16, 2025 16:50
Show Gist options
  • Select an option

  • Save goranefbl/199bf262b06d3eabe5658d126e9b1098 to your computer and use it in GitHub Desktop.

Select an option

Save goranefbl/199bf262b06d3eabe5658d126e9b1098 to your computer and use it in GitHub Desktop.
WooCommerce Points Plugin for WordPress multisite WPGens
<?php
/**
* Multisite Points Synchronization for WPGens Loyalty Program
* Keeps points synchronized across all sites in a multisite network
*/
class WPGL_Multisite_Points_Sync {
private static $syncing = false; // Prevent infinite loops
public static function init() {
// Only run on multisite installations
if (!is_multisite()) {
return;
}
// Hook into points updates AFTER they're processed
add_action('wpgens_loyalty_points_updated', [__CLASS__, 'sync_points_across_sites'], 10, 5);
}
/**
* Sync points across all sites when points are updated
*/
public static function sync_points_across_sites($user_id, $new_balance, $points_delta, $type, $source) {
// Prevent infinite loops during sync
if (self::$syncing) {
return;
}
// Skip if this update was already a sync operation
if ($source === 'multisite_sync') {
return;
}
// Get current site ID
$current_site_id = get_current_blog_id();
// Get all sites in the network
$sites = get_sites([
'number' => 0, // Get all sites
'public' => 1 // Only public sites
]);
// Set sync flag to prevent loops
self::$syncing = true;
foreach ($sites as $site) {
// Skip current site (already updated)
if ($site->blog_id == $current_site_id) {
continue;
}
// Switch to the target site
switch_to_blog($site->blog_id);
try {
// Check if the plugin is active on this site
if (!class_exists('WPGL_Database')) {
continue;
}
// Get current balance on this site
$current_balance = WPGL_Database::get_user_points($user_id);
// Calculate the difference needed to match the new balance
$balance_difference = $new_balance - $current_balance;
// Only update if there's a difference
if ($balance_difference != 0) {
// Determine the activity type
$sync_type = $balance_difference > 0 ?
WPGL_Points_Activity_Type::EARN :
WPGL_Points_Activity_Type::DEDUCT;
// Create sync description
$description = sprintf(
'Synced from site %d: %s %d points',
$current_site_id,
$type,
abs($points_delta)
);
// Update points directly in database
WPGL_Database::update_user_points(
$user_id,
$balance_difference,
$sync_type,
'multisite_sync',
$current_site_id,
$description
);
}
} catch (Exception $e) {
error_log('Points sync error on site ' . $site->blog_id . ': ' . $e->getMessage());
}
// Restore original site
restore_current_blog();
}
// Reset sync flag
self::$syncing = false;
}
/**
* Manual sync function for existing users - syncs from main site to all others
*/
public static function manual_sync_all_users() {
if (!is_multisite() || !current_user_can('manage_network')) {
return false;
}
$sites = get_sites(['number' => 0, 'public' => 1]);
$main_site_id = get_main_site_id();
// Use main site as the source of truth
switch_to_blog($main_site_id);
if (!class_exists('WPGL_Database')) {
restore_current_blog();
return false;
}
// Get all users with points on main site
global $wpdb;
$users_with_points = $wpdb->get_results(
"SELECT user_id, points_balance
FROM {$wpdb->prefix}wpgens_loyalty_points_balance
WHERE points_balance > 0"
);
restore_current_blog();
self::$syncing = true;
// Sync each user to all other sites
foreach ($users_with_points as $user_data) {
foreach ($sites as $site) {
if ($site->blog_id == $main_site_id) continue;
switch_to_blog($site->blog_id);
if (class_exists('WPGL_Database')) {
$current_balance = WPGL_Database::get_user_points($user_data->user_id);
$difference = $user_data->points_balance - $current_balance;
if ($difference != 0) {
$type = $difference > 0 ?
WPGL_Points_Activity_Type::EARN :
WPGL_Points_Activity_Type::DEDUCT;
WPGL_Database::update_user_points(
$user_data->user_id,
$difference,
$type,
'multisite_sync',
$main_site_id,
'Manual sync from main site'
);
}
}
restore_current_blog();
}
}
self::$syncing = false;
return true;
}
}
// Initialize the sync system
add_action('plugins_loaded', ['WPGL_Multisite_Points_Sync', 'init']);
/**
* Admin interface for manual sync (Network Admin only)
*/
if (is_admin() && is_multisite()) {
add_action('network_admin_menu', function() {
add_submenu_page(
'settings.php',
'Sync Loyalty Points',
'Sync Loyalty Points',
'manage_network',
'sync-loyalty-points',
function() {
if (isset($_POST['sync_points']) && wp_verify_nonce($_POST['_wpnonce'], 'sync_points')) {
$result = WPGL_Multisite_Points_Sync::manual_sync_all_users();
echo '<div class="notice notice-' . ($result ? 'success' : 'error') . '"><p>';
echo $result ? 'Points synchronized successfully!' : 'Sync failed. Check error logs.';
echo '</p></div>';
}
echo '<div class="wrap">';
echo '<h1>Sync Loyalty Points Across Network</h1>';
echo '<form method="post">';
wp_nonce_field('sync_points');
echo '<p>This will sync all user points from the main site to all other sites in the network.</p>';
echo '<p><strong>Warning:</strong> This will overwrite points on other sites. Make sure to backup first!</p>';
submit_button('Sync All Points', 'primary', 'sync_points');
echo '</form>';
echo '</div>';
}
);
});
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment