Quantcast
Viewing all articles
Browse latest Browse all 4

gapi google analytics latest version with oauth 2.0

GAPI – Google Analytics PHP Interface is a good class to grab google analytics data.I think same as me there are lots of people used this interface in their projects,but now this class stopped upgrade and it’s become not steady.Google already have upgrade his Core Reporting API to version 3 and Authorization with oauth 2.0,It’s the time to upgrade our codes.

Problems of GAPI

I have used GAPI for a year,it’s did a great work,but recently i found it’s become not steady now .

1.It’s always throw “No valid root parameter…” error.I have checked with the feed result and found the problem:

<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xmlns:dxp="http://schemas.google.com/analytics/2009" xmlns:openSearch="http://a9.com/-/spec/opensearch/1.1/">

check the “xmlns:openSearch” the value is “http://a9.com/-/spec/opensearch/1.0/” but sometimes its return “http://a9.com/-/spec/opensearch/1.1/”.Gapi use ‘http://a9.com/-/spec/opensearchrss/1.0/’ so it’s start throw ‘GAPI: Failed to request account data. Error:’ and become not steady.

2.GAPI use email and password login authorization,as a api it’s very bad.In order to grab user data you must provide login email and password,it’s a serious security problem.Use latest oauth 2.0 is the best choose.

Adjust GAPI with Core Reporting API to version 3

Why i need adjust GAPI and not use new api directly?.
As mentioned,i have used GAPI for a year and very familiar with it’s style.GAPI have helped me to grab hundreds of client’s data, I have to changes much codes to upgrade to new version.so I decide adjust GAPI with latest google Core Reporting API to version 3 sample codes and api class.
There is the new version the GAPI i have Adjusted

 
class gapi
{
 
  const dev_mode = false;  
  private  $analytics;
 
 
  function __construct(&$anlaytics) {
    $this->analytics = $anlaytics;
  }
 
   /**
   * Case insensitive array_key_exists function, also returns
   * matching key.
   *
   * @param String $key
   * @param Array $search
   * @return String Matching array key
   */
  public static function array_key_exists_nc($key, $search)
  {
 
    if (array_key_exists($key, $search))
    {
      return $key;
    }
    if (!(is_string($key) && is_array($search)))
    {
      return false;
    }
    $key = strtolower($key);
    foreach ($search as $k => $v)
    {
      if (strtolower($k) == $key)
      {
        return $k;
      }
    }
    return false;
  }
 
  /**
   * Request report data from Google Analytics
   *
   * $report_id is the Google report ID for the selected account
   * 
   * $parameters should be in key => value format
   * 
   * @param String $report_id
   * @param Array $dimensions Google Analytics dimensions e.g. array('browser')
   * @param Array $metrics Google Analytics metrics e.g. array('pageviews')
   * @param Array $sort_metric OPTIONAL: Dimension or dimensions to sort by e.g.('-visits')
   * @param String $filter OPTIONAL: Filter logic for filtering results
   * @param String $start_date OPTIONAL: Start of reporting period
   * @param String $end_date OPTIONAL: End of reporting period
   * @param Int $start_index OPTIONAL: Start index of results
   * @param Int $max_results OPTIONAL: Max results returned
   */
  public function requestReportData($profileId, $dimensions, $metrics, $sort_metric=null, $filter=null, $start_date=null, $end_date=null, $start_index=1, $max_results=100)
  {
     $this->report_root_parameters = array();
	 $this->results = array(); 
     $parameters=array();
	 $metrics_string = '';
    if($dimensions)
    if(is_array($dimensions))
    {
      $dimensions_string = '';
      foreach($dimensions as $dimesion)
      {
        $dimensions_string .= ',ga:' . $dimesion;
      }
      $parameters['dimensions'] = substr($dimensions_string,1);
    }
    else 
    {
      $parameters['dimensions'] = 'ga:'.$dimensions;
    }
 
    if(is_array($metrics))
    {
 
      foreach($metrics as $metric)
      {
        $metrics_string .= ',ga:' . $metric;
      }
       $metrics_string = substr($metrics_string,1);
    }
    else 
    {
       $metrics_string = 'ga:'.$metrics;
    }
 
 
    if($sort_metric==null && !empty( $metrics_string))
    {
      $parameters['sort'] =  $metrics_string;
    }
    elseif(is_array($sort_metric))
    {
      $sort_metric_string = '';
 
      foreach($sort_metric as $sort_metric_value)
      {
        //Reverse sort - Thanks Nick Sullivan
        if (substr($sort_metric_value, 0, 1) == "-")
        {
          $sort_metric_string .= ',-ga:' . substr($sort_metric_value, 1); // Descending
        }
        else
        {
          $sort_metric_string .= ',ga:' . $sort_metric_value; // Ascending
        }
      }
 
      $parameters['sort'] = substr($sort_metric_string, 1);
    }
    else 
    {
      if (substr($sort_metric, 0, 1) == "-")
      {
        $parameters['sort'] = '-ga:' . substr($sort_metric, 1);
      }
      else 
      {
        $parameters['sort'] = 'ga:' . $sort_metric;
      }
    }
 
    if($filter!=null)
    {
      $filter = $this->processFilter($filter);
      if($filter!==false)
      {
        $parameters['filters'] = $filter;
      }
    }
 
    if($start_date==null)
    {
      $start_date=date('Y-m-d',strtotime('1 month ago'));
    }
 
 
 
    if($end_date==null)
    {
      $end_date=date('Y-m-d');
    }
 
 
 
    $parameters['max-results'] = $max_results;
 
 
 
	 try {
			$result=$this->analytics->data_ga->get(
			'ga:' . $profileId,
			 $start_date,
			 $end_date,
			 $metrics_string,
			 $parameters);
 
		    $rows=$result->getRows();
			$this->results = null;
			$results = array();
 
			$report_root_parameters = array(); 
 
			$totals = $result->gettotalsForAllResults();		 
			foreach ($totals as  $metricName => $metricTotal )
			{ 
			  $report_root_parameters[str_replace('ga:','',$metricName)]=$metricTotal; 
			}   
 
			$report_root_parameters['totalResults']=$result->gettotalResults();
			$report_root_parameters['nextLink']=$result->getnextLink();
			$report_root_parameters['selfLink']=$result->getselfLink();
			$report_root_parameters['haveData']=count($rows)>0 ? true:false;
			if(count($rows)>0)
			{
			$metrics=Array();$dimensions = array();
			foreach ($result->getColumnHeaders() as $header) {
 
			   $metrics[]=str_replace('ga:','',$header->getName());
			   if($header->getColumnType()=='DIMENSION')
			   {
			     $dimensions[]=str_replace('ga:','',$header->getName());
			   }
		    }
			foreach ($rows as $row) {
			  $metric=Array();$dimension=Array();$i=0;
			  foreach ($row as $cell) {
 
					  $metric[$metrics[$i]]=$cell;
					  $i++;
 
			  }
			  foreach($dimensions as $v)
			  {
			    $dimension[$v]=$metric[$v];
			  }
			 $results[]= new gapiReportEntry ($metric,$dimension);
			}
			}
 
		 $this->report_root_parameters = $report_root_parameters;
 
		  $this->results = $results;
 
		return $results;
 
    }  catch ( Exception $e) {
 
 
	  throw new  Exception( $e->getMessage() );
 
    } 
 
    return '';
 
 
 
 
  }
 
  /**
   * Process filter string, clean parameters and convert to Google Analytics
   * compatible format
   * 
   * @param String $filter
   * @return String Compatible filter string
   */
  protected function processFilter($filter)
  {
    $valid_operators = '(!~|=~|==|!=|>|<|>=|<=|=@|!@)';
 
    $filter = preg_replace('/\s\s+/',' ',trim($filter)); //Clean duplicate whitespace
    $filter = str_replace(array(',',';'),array('\,','\;'),$filter); //Escape Google Analytics reserved characters
    $filter = preg_replace('/(&&\s*|\|\|\s*|^)([a-z]+)(\s*' . $valid_operators . ')/i','$1ga:$2$3',$filter); //Prefix ga: to metrics and dimensions
    $filter = preg_replace('/[\'\"]/i','',$filter); //Clear invalid quote characters
    $filter = preg_replace(array('/\s*&&\s*/','/\s*\|\|\s*/','/\s*' . $valid_operators . '\s*/'),array(';',',','$1'),$filter); //Clean up operators
 
    if(strlen($filter)>0)
    {
      return  ($filter);
    }
    else 
    {
      return false;
    }
  } 
  /**
   * Get Results
   *
   * @return Array
   */
  public function getResults()
  {
    if(is_array($this->results))
    {
      return $this->results;
    }
    else 
    {
      return;
    }
  }
 
 
 
  /**
   * Call method to find a matching root parameter or 
   * aggregate metric to return
   *
   * @param $name String name of function called
   * @return String
   * @throws Exception if not a valid parameter or aggregate 
   * metric, or not a 'get' function
   */
  public function __call($name,$parameters)
  {
    if(!preg_match('/^get/',$name))
    {
      throw new Exception('No such function "' . $name . '"');
    }
 
    $name = preg_replace('/^get/','',$name);
 
    $parameter_key = gapi::array_key_exists_nc($name,$this->report_root_parameters);
 
    if($parameter_key)
    {
      return $this->report_root_parameters[$parameter_key];
    }
 
    throw new Exception('No valid root parameter or aggregate metric called "' . $name . '"');
  }
 
 
}
 
 
/**
 * Class gapiReportEntry
 * 
 * Storage for individual gapi report entries
 *
 */
class gapiReportEntry
{
	  private $metrics = array();
	 private $dimensions = array();
	 public function __construct($metrics,$dimesions)
	 {
		$this->metrics = $metrics;
		$this->dimensions = $dimesions;
	 }
 
   public function __toString()
  {
    if(is_array($this->dimensions))
    {
      return implode(' ',$this->dimensions);
    }
    else 
    {
      return '';
    }
  } 
 
  /**
   * Get an array of the metrics and the matchning
   * values for the current result
   *
   * @return Array
   */
  public function getMetrics()
  {
    return $this->metrics;
  }
 
  /**
   * Call method to find a matching metric or dimension to return
   *
   * @param $name String name of function called
   * @return String
   * @throws Exception if not a valid metric or dimensions, or not a 'get' function
   */
  public function __call($name,$parameters)
  {
    if(!preg_match('/^get/',$name))
    {
      throw new Exception('No such function "' . $name . '"');
    }
 
    $name = preg_replace('/^get/','',$name);
 
    $metric_key = gapi::array_key_exists_nc($name,$this->metrics);
 
    if($metric_key)
    {
      return $this->metrics[$metric_key];
    }
 
 
 
    throw new Exception('No valid metric or dimesion called "' . $name . '"');
  }
}

How to use adjusted GAPI

To understand this part you need open a project in google apis console,if you not understand please check my follow post php get google analytics data use oauth 2.0.

 
const REDIRECT_URL = 'your redirect url';
const CLIENT_ID = 'your client id';
const CLIENT_SECRET = 'your client secret'; 
const APP_NAME = 'your app name';
const ANALYTICS_SCOPE = 'https://www.googleapis.com/auth/analytics.readonly';
 
 
// Build a new client object to work with authorization.
$client = new Google_Client();
$client->setClientId(CLIENT_ID);
$client->setClientSecret(CLIENT_SECRET);
$client->setRedirectUri(REDIRECT_URL);
$client->setApplicationName(APP_NAME);
$client->setScopes(array(ANALYTICS_SCOPE));
 
// Magic. Returns objects from the Analytics Service
// instead of associative arrays.
$client->setUseObjects(true); 
 
$accessToken= $_SESSION['token'];
if(empty($accessToken))
{
 header('Location:getGatoken.php');
}
$client->setAccessToken($accessToken);
if($client->isAccessTokenExpired())
{
    $tokenObj = json_decode($accessToken);
    $client->refreshToken($tokenObj->refresh_token);
    $_SESSION['token']=$client->getAccessToken();
}
 
 $ga_profile_id = 'you profile id';
 $analytics = new Google_AnalyticsService($client);
 
 $ga = new gapi($analytics);

then you do very thing as the old api now for instance

$ga->requestReportData($ga_profile_id,array('date'),array('pageviews','visits','bounces','newVisits','timeOnSite'),null,"medium==organic",$start_date, $end_date, 1, 32);  
 $totalvisits =  $ga->getVisits();
 $dailyvisits=$ga->getResults(); 
 
  foreach($dailyvisits as $result) 
	{ 
 
          $v= $result->getVisits(); 
           $date= trim($result);  
	   echo "$date visits $v of $totalvisits <br />";
	 }

you see it’s still your familiar GAPI style,the main function and the way we got data is not changed.It’s
Cool,Isn’t it?

Demo & Download

GAPI with Oauth 2.0 Demo.Download the zip, uncompression and upload to the root of your site,add your google console project access information to the config.php,then visit http://www.yoursite.com/Gaapi/getGatoken.php to start.Tested with PHP 5.3.


Viewing all articles
Browse latest Browse all 4

Trending Articles