Last active
October 16, 2025 16:50
-
-
Save goranefbl/199bf262b06d3eabe5658d126e9b1098 to your computer and use it in GitHub Desktop.
WooCommerce Points Plugin for WordPress multisite WPGens
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?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