Title: Switch_to_blog call in Users.php causing issues
Last modified: August 31, 2016

---

# Switch_to_blog call in Users.php causing issues

 *  [mbigler](https://wordpress.org/support/users/mbigler/)
 * (@mbigler)
 * [10 years, 3 months ago](https://wordpress.org/support/topic/switch_to_blog-call-in-usersphp-causing-issues/)
 * The switch_to_blog call in the ‘badgeos_get_network_achievement_types_for_user’
   function in the users.php file is causing issues with other plugins, in particular
   the ThreeWP Broadcast plugin.
 * There is never a call to restore_current_blog after the blog is switched, rather
   it switches back by calling switch_to_blog again with the cached blog id, but
   this is causing others plugins to view the blog as still being switched and preventing
   them from working.
 * I can fix the issue by replacing the second switch_to_blog call with a call to
   restore_current_blog but then I am no longer able to have the badgeos community
   add on activated, as doing so breaks all admin navigation and redirects all links
   to one child site.
 * I would like to be able to continue to use both badgeos and the community add
   on. Any help is appreciated.
 * [https://wordpress.org/plugins/badgeos/](https://wordpress.org/plugins/badgeos/)

Viewing 10 replies - 1 through 10 (of 10 total)

 *  [Michael Beckwith](https://wordpress.org/support/users/tw2113/)
 * (@tw2113)
 * The BenchPresser
 * [10 years, 3 months ago](https://wordpress.org/support/topic/switch_to_blog-call-in-usersphp-causing-issues/#post-7327288)
 * Curious if part of [https://github.com/opencredit/badgeos/issues/431](https://github.com/opencredit/badgeos/issues/431)
   would be related.
 * Specifically:
 *     ```
       It's worth considering switching back to the previous in the site array stack at the end of every iteration in our foreach loop.
       ```
   
 * the admin navigation/redirects issue is a curious one from your feedback.
 *  Thread Starter [mbigler](https://wordpress.org/support/users/mbigler/)
 * (@mbigler)
 * [10 years, 3 months ago](https://wordpress.org/support/topic/switch_to_blog-call-in-usersphp-causing-issues/#post-7327372)
 * Thank you for the timely response. I would guess that the two issues are related,
   and I would bet that restoring the blog after each iteration would fix the problem.
 * Upon further investigation with the code changed to restore the current blog,
   as I mentioned before, and the community add on activated, the navigation is 
   working but certain elements of the page are pulling information from what appears
   to be the second to last blog that was accessed in the foreach loop. For instance
   the link to visit the front end of the blog that is on the admin toolbar is stuck
   on that same site, the second to last one in the loop, regardless of which blog
   I visit. Also other plugins are no longer able to identify which blog I am on;
   so, plugins that require a license code, that aren’t enabled on the blog it is
   reporting that I am on, are behaving as if they have been installed on a new 
   site.
 * Thanks again for looking into this.
 *  [Michael Beckwith](https://wordpress.org/support/users/tw2113/)
 * (@tw2113)
 * The BenchPresser
 * [10 years, 3 months ago](https://wordpress.org/support/topic/switch_to_blog-call-in-usersphp-causing-issues/#post-7327392)
 * Just to be certain, have you tried tweaking the code to put the restore current
   blog inside the foreach and re-tested?
 *  Thread Starter [mbigler](https://wordpress.org/support/users/mbigler/)
 * (@mbigler)
 * [10 years, 3 months ago](https://wordpress.org/support/topic/switch_to_blog-call-in-usersphp-causing-issues/#post-7327412)
 * Sorry I should have pointed out that I hadn’t had a chance to yet.
 * I moved the is_multisite() test into the loop and replaced the switch_to_blog(
   $cached_id) with restore_current_blog() and normal operations seemed to be restored.
 * I found that leaving the is_multisite() test where it is and changing it to the
   following also works:
 *     ```
       if ( is_multisite() ) {
       	// Restore the original blog so the sky doesn't fall
       	switch_to_blog( $cached_id );
       	switch_to_blog( $cached_id );
       	restore_current_blog();
       }
       ```
   
 * I suppose if I was really ambitious I could dig in and see how restore_current_blog()
   actually works, but it seems as though the blog it references is always the blog
   you were on before the last call of switch_to_blog(). So, calling switch_to_blog(),
   with $cached_id set as the parameter, twice in a row, before calling restore_current_blog(),
   seems to do the trick.
 * There may be a more efficient way of accomplishing this, but I thought this might
   at least be more efficient than adding another function call to every iteration
   through the loop.
 *  [Michael Beckwith](https://wordpress.org/support/users/tw2113/)
 * (@tw2113)
 * The BenchPresser
 * [10 years, 3 months ago](https://wordpress.org/support/topic/switch_to_blog-call-in-usersphp-causing-issues/#post-7327424)
 * can you paste the entire function for me, the way you have it? It’ll be easier
   than me trying to mentally arrange the same way.
 *  Thread Starter [mbigler](https://wordpress.org/support/users/mbigler/)
 * (@mbigler)
 * [10 years, 3 months ago](https://wordpress.org/support/topic/switch_to_blog-call-in-usersphp-causing-issues/#post-7327432)
 * Sure thing
 *     ```
       function badgeos_get_network_achievement_types_for_user( $user_id ) {
       	global $blog_id;
   
       	// Store a copy of the original ID for later
       	$cached_id = $blog_id;
   
       	// Assume we have no achievement types
       	$all_achievement_types = array();
   
       	// Loop through all active sites
       	$sites = badgeos_get_network_site_ids();
       	foreach( $sites as $site_blog_id ) {
   
       		// If we're polling a different blog, switch to it
       		if ( $blog_id != $site_blog_id ) {
       			switch_to_blog( $site_blog_id );
       		}
   
       		// Merge earned achievements to our achievement type array
       		$achievement_types = badgeos_get_user_earned_achievement_types( $user_id );
       		if ( is_array($achievement_types) ) {
       			$all_achievement_types = array_merge($achievement_types,$all_achievement_types);
       		}
   
       	}
   
       	if ( is_multisite() ) {
       		// Restore the original blog so the sky doesn't fall
       		switch_to_blog( $cached_id );
       		switch_to_blog( $cached_id );
       		restore_current_blog();
       	}
   
       	// Pare down achievement type list so we return no duplicates
       	$achievement_types = array_unique( $all_achievement_types );
   
       	// Return all found achievements
       	return $achievement_types;
       }
       ```
   
 *  [Michael Beckwith](https://wordpress.org/support/users/tw2113/)
 * (@tw2113)
 * The BenchPresser
 * [10 years, 3 months ago](https://wordpress.org/support/topic/switch_to_blog-call-in-usersphp-causing-issues/#post-7327451)
 * I find it very odd that you’d need to run the switch_to_blog() with the same 
   cached ID twice.
 * From what I recall reading about in the past, these functions work on a global
   array of of IDs and other data, and they simply move the array pointers and whatnot
   through that array.
 * At least in my head, the lack of restore_current_blog() call would be covered
   by the switch back to the “cached” ID. The only way I can think of to have it
   not work as intended is if the variable gets overwritten by a fresh call to the
   function from a different site in the network.
 *  Thread Starter [mbigler](https://wordpress.org/support/users/mbigler/)
 * (@mbigler)
 * [10 years, 3 months ago](https://wordpress.org/support/topic/switch_to_blog-call-in-usersphp-causing-issues/#post-7327477)
 * Yeah I thought that was odd as well. BTW this works too:
 *     ```
       function badgeos_get_network_achievement_types_for_user( $user_id ) {
       	global $blog_id;
   
       	// Store a copy of the original ID for later
       	$cached_id = $blog_id;
   
       	// Assume we have no achievement types
       	$all_achievement_types = array();
   
       	// Loop through all active sites
       	$sites = badgeos_get_network_site_ids();
       	foreach( $sites as $site_blog_id ) {
   
       		// If we're polling a different blog, switch to it
       		if ( $blog_id != $site_blog_id ) {
       			switch_to_blog( $site_blog_id );
       		}
   
       		// Merge earned achievements to our achievement type array
       		$achievement_types = badgeos_get_user_earned_achievement_types( $user_id );
       		if ( is_array($achievement_types) ) {
       			$all_achievement_types = array_merge($achievement_types,$all_achievement_types);
       		}
   
       	if ( is_multisite() ) {
       		// Restore the original blog so the sky doesn't fall
       		restore_current_blog();
       		}		
   
       	}
   
       	// Pare down achievement type list so we return no duplicates
       	$achievement_types = array_unique( $all_achievement_types );
   
       	// Return all found achievements
       	return $achievement_types;
       }
       ```
   
 * I just figured the first solution would be more efficient. It would seem that
   switch_to_blog() must be populating some global variable that is overwritten 
   every time the function is called, and it would seem that restore_current_blog()
   must be referencing that same variable. Again, this is just an observation based
   on the way the functions appear to behave, as I haven’t dug into the source to
   see how they actually operate. Though, if that is true, and another plug-in is
   checking that global variable to see if the blog has been switched it would seem
   reasonable to think that would result in the problem I was having. The fix I 
   have in place seems to be working without issue though.
 *  Thread Starter [mbigler](https://wordpress.org/support/users/mbigler/)
 * (@mbigler)
 * [10 years, 3 months ago](https://wordpress.org/support/topic/switch_to_blog-call-in-usersphp-causing-issues/#post-7327478)
 * Ok, so I went ahead and dug into it and switch_to_blog() is using a global array
   as you thought, but there are two issues resulting in the problem I was having.
   The first is that restore_current_blog() actually only references the previous
   blog in that array. The second is that a global variable called ‘switched’ is
   also being set to true when switch to blog is called. So, the following working
   solution may be the best way to do it:
 *     ```
       function badgeos_get_network_achievement_types_for_user( $user_id ) {
       	global $blog_id;
   
       	// Store a copy of the original ID for later
       	$cached_id = $blog_id;
   
       	// Assume we have no achievement types
       	$all_achievement_types = array();
   
       	// Loop through all active sites
       	$sites = badgeos_get_network_site_ids();
       	foreach( $sites as $site_blog_id ) {
   
       		// If we're polling a different blog, switch to it
       		if ( $blog_id != $site_blog_id ) {
       			switch_to_blog( $site_blog_id );
       		}
   
       		// Merge earned achievements to our achievement type array
       		$achievement_types = badgeos_get_user_earned_achievement_types( $user_id );
       		if ( is_array($achievement_types) ) {
       			$all_achievement_types = array_merge($achievement_types,$all_achievement_types);
       		}
   
       	}
   
       	if ( is_multisite() ) {
       		// Restore the original blog so the sky doesn't fall
       		switch_to_blog( $cached_id );
       		$GLOBALS['switched'] = FALSE;
                       $GLOBALS['_wp_switched_stack'] = array();
       	}
   
       	// Pare down achievement type list so we return no duplicates
       	$achievement_types = array_unique( $all_achievement_types );
   
       	// Return all found achievements
       	return $achievement_types;
       }
       ```
   
 *  [jimmertek](https://wordpress.org/support/users/jimmertek/)
 * (@jimmertek)
 * [9 years, 5 months ago](https://wordpress.org/support/topic/switch_to_blog-call-in-usersphp-causing-issues/#post-8881039)
 * I’m now having the same issue but cannot see any of that code in the plugin. 
   Can you please let us know if there was a solution? We are using the plugin Broadcast
   which doesn’t work when Badge OS Community AddOn is enabled.

Viewing 10 replies - 1 through 10 (of 10 total)

The topic ‘Switch_to_blog call in Users.php causing issues’ is closed to new replies.

 * ![](https://s.w.org/plugins/geopattern-icon/badgeos_85d3bc.svg)
 * [BadgeOS](https://wordpress.org/plugins/badgeos/)
 * [Frequently Asked Questions](https://wordpress.org/plugins/badgeos/#faq)
 * [Support Threads](https://wordpress.org/support/plugin/badgeos/)
 * [Active Topics](https://wordpress.org/support/plugin/badgeos/active/)
 * [Unresolved Topics](https://wordpress.org/support/plugin/badgeos/unresolved/)
 * [Reviews](https://wordpress.org/support/plugin/badgeos/reviews/)

## Tags

 * [switched](https://wordpress.org/support/topic-tag/switched/)
 * [threewp](https://wordpress.org/support/topic-tag/threewp/)

 * 10 replies
 * 3 participants
 * Last reply from: [jimmertek](https://wordpress.org/support/users/jimmertek/)
 * Last activity: [9 years, 5 months ago](https://wordpress.org/support/topic/switch_to_blog-call-in-usersphp-causing-issues/#post-8881039)
 * Status: not resolved