Google Analytics for WordPress Fixed

“Unfortunately, an error occurred while connecting to Google”

Yoast Google Analytics for WordPress

Google Analytics for WordPress is a great plugin by Yoast to make adding Analytics tracking to your WordPress site easy. All was well until Google updated their authentication and authorization APIs, thus breaking the plugin’s ability to load your Google Analytics accounts and properties using your Google credentials via OpenID and OAuth. The error that comes back in this case is "Unfortunately, an error occurred while connecting to Google" but no additional information on what exactly the problem was. It has been broken for some time now, and although you can enter your UA code manually, I decided to just fix the code in question.

In a nutshell Google updated their URLs and transitioned from an XML interface to a JSON RESTful web service. The changes are pretty straightforward, but now require two calls to Google to get both the Analytics Accounts associated with your username/auth token and a second one to get all of the Analytics Properties (though they can be loaded for all properties at the same time by using ~all in place of the account id in the request.

The file to modify lives under /wp-content/plugins/google-analytics-for-wordpress/googleanalytics.php. Here is what the code looks like in my version, currently the latest, at 4.2.8. and starts on line 383 and ends on line 435. Replace the code here with the code below it:

// ... Opening code
	$response  = $gdata->get( 'https://www.google.com/analytics/feeds/accounts/default' );
	$http_code = wp_remote_retrieve_response_code( $response );
	$response  = wp_remote_retrieve_body( $response );

	if ( $http_code == 200 ) {
		$options['ga_api_responses'][$token] = array(
			'response'=> array( 'code'=> $http_code ),
			'body'    => $response
		);
		$options['ga_token']                 = $token;
		update_option( 'Yoast_Google_Analytics', $options );
	}
}

if ( isset( $options['ga_api_responses'][$token] ) && is_array( $options['ga_api_responses'][$token] ) && $options['ga_api_responses'][$token]['response']['code'] == 200 ) {
	$arr = yoast_xml2array( $options['ga_api_responses'][$token]['body'] );

	$ga_accounts = array();
	if ( isset( $arr['feed']['entry'][0] ) ) {
		foreach ( $arr['feed']['entry'] as $site ) {
			$ua      = $site['dxp:property']['3_attr']['value'];
			$account = $site['dxp:property']['1_attr']['value'];
			if ( !isset( $ga_accounts[$account] ) || !is_array( $ga_accounts[$account] ) )
				$ga_accounts[$account] = array();
			$ga_accounts[$account][$site['title']] = $ua;
		}
	} else {
		$ua      = $arr['feed']['entry']['dxp:property']['3_attr']['value'];
		$account = $arr['feed']['entry']['dxp:property']['1_attr']['value'];
		$title   = $arr['feed']['entry']['title'];
		if ( !isset( $ga_accounts[$account] ) || !is_array( $ga_accounts[$account] ) )
			$ga_accounts[$account] = array();
		$ga_accounts[$account][$title] = $ua;
	}
// ... Closing code

The modified code looks like this:

// ... Opening code
	// Get all of the Accounts for this oauth token
	$url = 'https://www.googleapis.com/analytics/v3/management/accounts';
	$response  = $gdata->get( $url );
	$http_code = wp_remote_retrieve_response_code( $response );
	$response  = wp_remote_retrieve_body( $response );

	if ( $http_code == 200 ) {
		$options['ga_api_responses'][$token] = array(
			'acct_response'=> array( 'code'=> $http_code ),
			'acct_body'    => $response
		);

		// Get all of the properties for this oauth token
		$url = 'https://www.googleapis.com/analytics/v3/management/accounts/~all/webproperties/';
		$response  = $gdata->get( $url );
		$http_code = wp_remote_retrieve_response_code( $response );
		$response  = wp_remote_retrieve_body( $response );

		if ( $http_code == 200 ) {
			$options['ga_api_responses'][$token]['response'] = array( 'code'=> $http_code );
			$options['ga_api_responses'][$token]['body'] = $response;

			$options['ga_token']                 = $token;
			update_option( 'Yoast_Google_Analytics', $options );
		}
	}
}

if ( isset( $options['ga_api_responses'][$token] ) && is_array( $options['ga_api_responses'][$token] ) && $options['ga_api_responses'][$token]['response']['code'] == 200 ) {

	// Get all of the accounts so we can reference the name by ID
	$account_info = array();
	$json = json_decode( $options['ga_api_responses'][$token]['acct_body'] );
	foreach ($json->items as $item) {
		$account_id = strval($item->id);
		$account_info[$account_id] = $item->name;
	}

	// Get all of the properties in to an array
	$ga_accounts = array();
	$json = json_decode( $options['ga_api_responses'][$token]['body'] );
	foreach ($json->items as $item) {
		$account_id = strval($item->accountId);
		$account = $account_info[$account_id];
		$ua = $item->id;
		$title = $item->name; 

		// make sure we have an arrary created to hold the properties
		if ( !isset( $ga_properties[$account] ) || !is_array( $ga_properties[$account] ) )
			$ga_accounts[$account] = array();

		// Save the property by account for display
		$ga_accounts[$account][$title] = $ua;
	}
// ... Closing code

You may also like...

4 Responses

  1. Extreme Gain says:

    An impressive share! I’ve just forwarded this onto a colleague who was doing a little homework on this. And he in fact ordered me breakfast due to the fact that I found it for him… lol. So allow me to reword this…. Thank YOU for the meal!! But yeah, thanx for spending some time to talk about this topic here on your internet site.

  2. Calvin says:

    Now this is how you fix something. Not with a workaround and using a “manual” solution as so many other people suggested, but with an actual code fix. Thanks for providing it. Once your code fix was properly applied, the Google Analytics for WordPress Configuration window instantly showed the available profiles. Two seconds late the code was in the site header where it was suppose to be. Hopefully Yoast can apply your fix sooner than later and give you credit :O)

  3. Alex says:

    Thanks a lot, this was exactly what I needed. Your code worked great! Did you try contacting Yoast yet so he can add this to his code and update it?

    Thanks!

    • Justin Silver says:

      Glad to hear it worked for you! I did send Yoast an email the other day but haven’t heard back yet 🙂

Leave a Reply

Your email address will not be published. Required fields are marked *