class analytics_api {
public $auth;
public $accounts;
public function login($email, $password) {
$ch = $this->curl_init("https://www.google.com/accounts/ClientLogin");
curl_setopt($ch, CURLOPT_POST, true);
$data = array(
'accountType' => 'GOOGLE',
'Email' => $email,
'Passwd' => $password,
'service' => 'analytics',
'source' => ''
);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
$output = curl_exec($ch);
$info = curl_getinfo($ch);
curl_close($ch);
$this->auth = '';
if($info['http_code'] == 200) {
preg_match('/Auth=(.*)/', $output, $matches);
if(isset($matches[1])) {
$this->auth = $matches[1];
}
}
return $this->auth != '';
}
public function call($url) {
$headers = array("Authorization: GoogleLogin auth=$this->auth");
$ch = $this->curl_init($url);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
$output = curl_exec($ch);
$info = curl_getinfo($ch);
curl_close($ch);
$return = false;
if($info['http_code'] == 200) {
$return = $output;
}
elseif($info['http_code'] == 400) {
trigger_error('Badly formatted request to the Google Analytics API; check your profile id is in the format ga:12345, dates are correctly formatted and the dimensions and metrics are correct', E_USER_WARNING);
}
elseif($info['http_code'] == 401) {
trigger_error('Unauthorized request to the Google Analytics API', E_USER_WARNING);
}
else {
trigger_error("Unknown error when accessing the Google Analytics API, HTTP STATUS {$info['http_code']}", E_USER_WARNING);
}
return $return;
}
public function load_accounts() {
$xml = $this->call('https://www.google.com/analytics/feeds/accounts/default');
$dom = new DOMDocument();
$dom->loadXML($xml);
$entries = $dom->getElementsByTagName('entry');
$this->accounts = array();
foreach($entries as $entry) {
$titles = $entry->getElementsByTagName('title');
$title = $titles->item(0)->nodeValue;
$this->accounts[$title] = array('title' => $title);
$tableIds = $entry->getElementsByTagName('tableId');
$this->accounts[$title]['tableId'] = $tableIds->item(0)->nodeValue;
$properties = $entry->getElementsByTagName('property');
foreach($properties as $property) {
switch($property->getAttribute('name')) {
case 'ga:accountId':
$this->accounts[$title]['accountId'] = $property->getAttribute('value');
break;
case 'ga:accountName':
$this->accounts[$title]['accountName'] = $property->getAttribute('value');
break;
case 'ga:webPropertyId':
$this->accounts[$title]['webPropertyId'] = $property->getAttribute('value');
break;
case 'ga:profileId':
$this->accounts[$title]['profileId'] = $property->getAttribute('value');
break;
}
}
}
ksort($this->accounts);
}
public function data($id, $dimension, $metric, $sort = false, $start = false, $end = false, $max_results = 10, $start_index = 1, $filters = false, $debug = false) {
if(!$sort) $sort = "-$metric";
if($start == 'today') {
$start = date('Y-m-d');
$end = $start;
}
elseif($start == 'yesterday') {
$start = date('Y-m-d', strtotime('yesterday'));
$end = $start;
}
elseif($start == 'week') {
$start = date('Y-m-d', strtotime('1 week ago'));
$end = date('Y-m-d', strtotime('yesterday'));
}
else {
if(!$start) $start = date('Y-m-d', strtotime('1 month ago'));
if(!$end) $end = date('Y-m-d', strtotime('yesterday'));
}
$url = "https://www.google.com/analytics/feeds/data?ids=$id&dimensions=$dimension&metrics=$metric&sort=$sort&start-date=$start&end-date=$end&max-results=$max_results&start-index=$start_index";
if($filters) {
if(is_object($filters) && is_a($filters, 'analytics_filters') && $filters->filters) {
$url .= "&filters=" . $filters->filters;
}
elseif(is_string($filters)) {
$url .= "&filters=$filters";
}
}
if($debug) {
if(PHP_SAPI == 'cli') {
echo "$url\n";
}
else {
echo "" . htmlentities($url) . "
\n";
}
}
$xml = $this->call($url);
if(!$xml) {
return false;
}
$dom = new DOMDocument();
$dom->loadXML($xml);
$entries = $dom->getElementsByTagName('entry');
$data = array();
foreach($entries as $entry) {
$index = array();
foreach($entry->getElementsByTagName('dimension') as $mydimension) {
$index[] = $mydimension->getAttribute('value');
}
switch(count($index)) {
case 0:
foreach($entry->getElementsByTagName('metric') as $metric) {
$data[$metric->getAttribute('name')] = $metric->getAttribute('value');
}
break;
case 1:
foreach($entry->getElementsByTagName('metric') as $metric) {
$data[$index[0]][$metric->getAttribute('name')] = $metric->getAttribute('value');
}
break;
case 2:
foreach($entry->getElementsByTagName('metric') as $metric) {
$data[$index[0]][$index[1]][$metric->getAttribute('name')] = $metric->getAttribute('value');
}
break;
case 3:
foreach($entry->getElementsByTagName('metric') as $metric) {
$data[$index[0]][$index[1]][$index[2]][$metric->getAttribute('name')] = $metric->getAttribute('value');
}
break;
}
}
return $data;
}
public function get_summary($id, $start = false, $end = false, $filters = false, $debug = false) {
$data = $this->data($id, '', 'ga:visits,ga:pageviews,ga:timeOnSite', false, $start, $end, 10, 1, $filters, $debug);
if($data['ga:visits']) {
$data['average_time_on_site'] = $data['ga:timeOnSite'] / $data['ga:visits'];
$data['average_time_on_site_formatted'] = $this->sec2hms($data['ga:timeOnSite'] / $data['ga:visits']);
$data['pages_per_visit'] = sprintf('%0.2f', ($data['ga:pageviews'] / $data['ga:visits']));
}
else {
$data['ga:visits'] = 0;
$data['ga:pageviews'] = 0;
$data['ga:timeOnSite'] = "0.00";
$data['average_time_on_site'] = 0;
$data['average_time_on_site_formatted'] = $this->sec2hms(0);
$data['pages_per_visit'] = "0.00";
}
return $data;
}
public function get_summaries($start = false, $end = false, $filters = false, $debug = false) {
if(!$this->accounts) {
$this->load_accounts();
}
$data = array();
foreach($this->accounts as $account) {
$data[$account['title']] = $this->get_summary($account['tableId'], $start, $end, $filters, $debug);
}
return $data;
}
protected function curl_init($url) {
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
if($this->auth) {
curl_setopt($ch, CURLOPT_HTTPHEADER, array("Authorization: GoogleLogin auth=$this->auth"));
}
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 30);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
return $ch;
}
public function sec2hms($sec, $padHours = false) {
$hms = "";
$hours = intval(intval($sec) / 3600);
$hms .= ($padHours)
? str_pad($hours, 2, "0", STR_PAD_LEFT). ':'
: $hours. ':';
$minutes = intval(($sec / 60) % 60);
$hms .= str_pad($minutes, 2, "0", STR_PAD_LEFT). ':';
$seconds = intval($sec % 60);
$hms .= str_pad($seconds, 2, "0", STR_PAD_LEFT);
return $hms;
}
}
class analytics_filters {
public $filters;
public function __construct($dimension_or_metric, $comparison, $value) {
$this->filters = $dimension_or_metric . urlencode($comparison.$value);
}
public function add_and($dimension_or_metric, $comparison, $value) {
$this->filters .= ';' . $dimension_or_metric . urlencode($comparison.$value);
}
public function add_or($dimension_or_metric, $comparison, $value) {
$this->filters .= ',' . $dimension_or_metric . urlencode($comparison.$value);
}
}