diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..ebfafa5
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,4 @@
+vendor/*
+.git/*
+
+settings.php
\ No newline at end of file
diff --git a/GoogleAnalyticsAPI.class.php b/GoogleAnalyticsAPI.class.php
deleted file mode 100644
index 2762e44..0000000
--- a/GoogleAnalyticsAPI.class.php
+++ /dev/null
@@ -1,730 +0,0 @@
-
- *
- * @version 1.1
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- *
- *
- */
-class GoogleAnalyticsAPI {
-
- const API_URL = 'https://www.googleapis.com/analytics/v3/data/ga';
- const WEBPROPERTIES_URL = 'https://www.googleapis.com/analytics/v3/management/accounts/~all/webproperties';
- const PROFILES_URL = 'https://www.googleapis.com/analytics/v3/management/accounts/~all/webproperties/~all/profiles';
-
- public $auth = null;
- protected $accessToken = '';
- protected $accountId = '';
- protected $assoc = true;
-
- /**
- * Default query parameters
- *
- */
- protected $defaultQueryParams = array();
-
-
- /**
- * Constructor
- *
- * @access public
- * @param String $auth (default: 'web') 'web' for Web-applications with end-users involved, 'service' for service applications (server-to-server)
- */
- public function __construct($auth='web') {
-
- if (!function_exists('curl_init')) throw new Exception('The curl extension for PHP is required.');
- $this->auth = ($auth == 'web') ? new GoogleOauthWeb() : new GoogleOauthService();
- $this->defaultQueryParams = array(
- 'start-date' => date('Y-m-d', strtotime('-1 month')),
- 'end-date' => date('Y-m-d'),
- 'metrics' => 'ga:visits',
- );
-
- }
-
- public function __set($key, $value) {
-
- switch ($key) {
- case 'auth' :
- if (($value instanceof GoogleOauth) == false) {
- throw new Exception('auth needs to be a subclass of GoogleOauth');
- }
- $this->auth = $value;
- break;
- case 'defaultQueryParams' :
- $this->setDefaultQueryParams($value);
- break;
- default:
- $this->{$key} = $value;
- }
-
- }
-
- public function setAccessToken($token) {
- $this->accessToken = $token;
- }
-
- public function setAccountId($id) {
- $this->accountId = $id;
- }
-
- /**
- * Set default query parameters
- * Useful settings: start-date, end-date, max-results
- *
- * @access public
- * @param array() $params Query parameters
- */
- public function setDefaultQueryParams(array $params) {
- $params = array_merge($this->defaultQueryParams, $params);
- $this->defaultQueryParams = $params;
- }
-
-
- /**
- * Return objects from json_decode instead of arrays
- *
- * @access public
- * @param mixed $bool true to return objects
- */
- public function returnObjects($bool) {
- $this->assoc = !$bool;
- $this->auth->returnObjects($bool);
- }
-
-
- /**
- * Query the Google Analytics API
- *
- * @access public
- * @param array $params (default: array()) Query parameters
- * @return array data
- */
- public function query($params=array()) {
- return $this->_query($params);
- }
-
-
- /**
- * Get all WebProperties
- *
- * @access public
- * @return array data
- */
- public function getWebProperties() {
-
- if (!$this->accessToken) throw new Exception('You must provide an accessToken');
-
- $data = Http::curl(self::WEBPROPERTIES_URL, array('access_token' => $this->accessToken));
- return json_decode($data, $this->assoc);
-
- }
-
-
- /**
- * Get all Profiles
- *
- * @access public
- * @return array data
- */
- public function getProfiles() {
-
- if (!$this->accessToken) throw new Exception('You must provide an accessToken');
-
- $data = Http::curl(self::PROFILES_URL, array('access_token' => $this->accessToken));
- return json_decode($data, $this->assoc);
-
- }
-
- /*****************************************************************************************************************************
- *
- * The following methods implement queries for the most useful statistics, seperated by topics: Audience/Content/Traffic Sources
- *
- *****************************************************************************************************************************/
-
- /*
- * AUDIENCE
- *
- */
-
- public function getVisitsByDate($params=array()) {
-
- $defaults = array(
- 'metrics' => 'ga:visits',
- 'dimensions' => 'ga:date',
- );
- $_params = array_merge($defaults, $params);
- return $this->_query($_params);
-
- }
-
- public function getAudienceStatistics($params=array()) {
-
- $defaults = array(
- 'metrics' => 'ga:visitors,ga:newVisits,ga:percentNewVisits,ga:visits,ga:bounces,ga:pageviews,ga:visitBounceRate,ga:timeOnSite,ga:avgTimeOnSite',
- );
- $_params = array_merge($defaults, $params);
- return $this->_query($_params);
-
- }
-
- public function getVisitsByCountries($params=array()) {
-
- $defaults = array(
- 'metrics' => 'ga:visits',
- 'dimensions' => 'ga:country',
- 'sort' => '-ga:visits',
- );
- $_params = array_merge($defaults, $params);
- return $this->_query($_params);
-
- }
-
- public function getVisitsByCities($params=array()) {
-
- $defaults = array(
- 'metrics' => 'ga:visits',
- 'dimensions' => 'ga:city',
- 'sort' => '-ga:visits',
- );
- $_params = array_merge($defaults, $params);
- return $this->_query($_params);
-
- }
-
- public function getVisitsByLanguages($params=array()) {
-
- $defaults = array(
- 'metrics' => 'ga:visits',
- 'dimensions' => 'ga:language',
- 'sort' => '-ga:visits',
- );
- $_params = array_merge($defaults, $params);
- return $this->_query($_params);
-
- }
-
- public function getVisitsBySystemBrowsers($params=array()) {
-
- $defaults = array(
- 'metrics' => 'ga:visits',
- 'dimensions' => 'ga:browser',
- 'sort' => '-ga:visits',
- );
- $_params = array_merge($defaults, $params);
- return $this->_query($_params);
-
- }
-
- public function getVisitsBySystemOs($params=array()) {
-
- $defaults = array(
- 'metrics' => 'ga:visits',
- 'dimensions' => 'ga:operatingSystem',
- 'sort' => '-ga:visits',
- );
- $_params = array_merge($defaults, $params);
- return $this->_query($_params);
-
-
- }
-
- public function getVisitsBySystemResolutions($params=array()) {
-
- $defaults = array(
- 'metrics' => 'ga:visits',
- 'dimensions' => 'ga:screenResolution',
- 'sort' => '-ga:visits',
- );
- $_params = array_merge($defaults, $params);
- return $this->_query($_params);
-
- }
-
- public function getVisitsByMobileOs($params=array()) {
-
- $defaults = array(
- 'metrics' => 'ga:visits',
- 'dimensions' => 'ga:operatingSystem',
- 'sort' => '-ga:visits',
- 'segment' => 'gaid::-11',
- );
- $_params = array_merge($defaults, $params);
- return $this->_query($_params);
-
- }
-
- public function getVisitsByMobileResolutions($params=array()) {
-
- $defaults = array(
- 'metrics' => 'ga:visits',
- 'dimensions' => 'ga:screenResolution',
- 'sort' => '-ga:visits',
- 'segment' => 'gaid::-11',
- );
- $_params = array_merge($defaults, $params);
- return $this->_query($_params);
-
- }
-
- /*
- * CONTENT
- *
- */
-
- public function getPageviewsByDate($params=array()) {
-
- $defaults = array(
- 'metrics' => 'ga:pageviews',
- 'dimensions' => 'ga:date',
- );
- $_params = array_merge($defaults, $params);
- return $this->_query($_params);
-
- }
-
- public function getContentStatistics($params=array()) {
-
- $defaults = array(
- 'metrics' => 'ga:pageviews,ga:uniquePageviews',
- );
- $_params = array_merge($defaults, $params);
- return $this->_query($_params);
-
- }
-
- public function getContentTopPages($params=array()) {
-
- $defaults = array(
- 'metrics' => 'ga:pageviews',
- 'dimensions' => 'ga:pagePath',
- 'sort' => '-ga:pageviews',
- );
- $_params = array_merge($defaults, $params);
- return $this->_query($_params);
-
- }
-
- /*
- * TRAFFIC SOURCES
- *
- */
-
- public function getTrafficSources($params=array()) {
-
- $defaults = array(
- 'metrics' => 'ga:visits',
- 'dimensions' => 'ga:medium',
- );
- $_params = array_merge($defaults, $params);
- return $this->_query($_params);
-
- }
-
- public function getKeywords($params=array()) {
-
- $defaults = array(
- 'metrics' => 'ga:visits',
- 'dimensions' => 'ga:keyword',
- 'sort' => '-ga:visits',
- );
- $_params = array_merge($defaults, $params);
- return $this->_query($_params);
-
- }
-
- public function getReferralTraffic($params=array()) {
-
- $defaults = array(
- 'metrics' => 'ga:visits',
- 'dimensions' => 'ga:source',
- 'sort' => '-ga:visits',
- );
- $_params = array_merge($defaults, $params);
- return $this->_query($_params);
-
- }
-
-
- protected function _query($params=array()){
-
- if (!$this->accessToken || !$this->accountId) {
- throw new Exception('You must provide the accessToken and an accountId');
- }
- $_params = array_merge($this->defaultQueryParams, array('access_token' => $this->accessToken, 'ids' => $this->accountId));
- $queryParams = array_merge($_params, $params);
- $data = Http::curl(self::API_URL, $queryParams);
- return json_decode($data, $this->assoc);
-
- }
-
-}
-
-
-/**
- * Abstract Auth class
- *
- */
-abstract class GoogleOauth {
-
- const TOKEN_URL = 'https://accounts.google.com/o/oauth2/token';
- const SCOPE_URL = 'https://www.googleapis.com/auth/analytics.readonly';
-
- protected $assoc = true;
- protected $clientId = '';
-
- public function __set($key, $value) {
- $this->{$key} = $value;
- }
-
- public function setClientId($id) {
- $this->clientId = $id;
- }
-
- public function returnObjects($bool) {
- $this->assoc = !$bool;
- }
-
- /**
- * To be implemented by the subclasses
- *
- */
- public function getAccessToken($data=null) {}
-
-}
-
-
-/**
- * Oauth 2.0 for service applications requiring a private key
- * openssl extension for PHP is required!
- * @extends GoogleOauth
- *
- */
-class GoogleOauthService extends GoogleOauth {
-
- const MAX_LIFETIME_SECONDS = 3600;
- const GRANT_TYPE = 'urn:ietf:params:oauth:grant-type:jwt-bearer';
-
- protected $email = '';
- protected $privateKey = null;
- protected $password = 'notasecret';
-
- /**
- * Constructor
- *
- * @access public
- * @param string $clientId (default: '') Client-ID of your project from the Google APIs console
- * @param string $email (default: '') E-Mail address of your project from the Google APIs console
- * @param mixed $privateKey (default: null) Path to your private key file (*.p12)
- */
- public function __construct($clientId='', $email='', $privateKey=null) {
- if (!function_exists('openssl_sign')) throw new Exception('openssl extension for PHP is needed.');
- $this->clientId = $clientId;
- $this->email = $email;
- $this->privateKey = $privateKey;
- }
-
-
- public function setEmail($email) {
- $this->email = $email;
- }
-
- public function setPrivateKey($key) {
- $this->privateKey = $key;
- }
-
-
- /**
- * Get the accessToken in exchange with the JWT
- *
- * @access public
- * @param mixed $data (default: null) No data needed in this implementation
- * @return array Array with keys: access_token, expires_in
- */
- public function getAccessToken($data=null) {
-
- if (!$this->clientId || !$this->email || !$this->privateKey) {
- throw new Exception('You must provide the clientId, email and a path to your private Key');
- }
-
- $jwt = $this->generateSignedJWT();
-
- $params = array(
- 'grant_type' => self::GRANT_TYPE,
- 'assertion' => $jwt,
- );
-
- $auth = Http::curl(GoogleOauth::TOKEN_URL, $params, true);
- return json_decode($auth, $this->assoc);
-
- }
-
-
- /**
- * Generate and sign a JWT request
- * See: https://developers.google.com/accounts/docs/OAuth2ServiceAccount
- *
- * @access protected
- */
- protected function generateSignedJWT() {
-
- // Check if a valid privateKey file is provided
- if (!file_exists($this->privateKey) || !is_file($this->privateKey)) {
- throw new Exception('Private key does not exist');
- }
-
- // Create header, claim and signature
- $header = array(
- 'alg' => 'RS256',
- 'typ' => 'JWT',
- );
-
- $t = time();
- $params = array(
- 'iss' => $this->email,
- 'scope' => GoogleOauth::SCOPE_URL,
- 'aud' => GoogleOauth::TOKEN_URL,
- 'exp' => $t + self::MAX_LIFETIME_SECONDS,
- 'iat' => $t,
- );
-
- $encodings = array(
- base64_encode(json_encode($header)),
- base64_encode(json_encode($params)),
- );
-
- // Compute Signature
- $input = implode('.', $encodings);
- $certs = array();
- $pkcs12 = file_get_contents($this->privateKey);
- if (!openssl_pkcs12_read($pkcs12, $certs, $this->password)) {
- throw new Exception('Could not parse .p12 file');
- }
- if (!isset($certs['pkey'])) {
- throw new Exception('Could not find private key in .p12 file');
- }
- $keyId = openssl_pkey_get_private($certs['pkey']);
- if (!openssl_sign($input, $sig, $keyId, 'sha256')) {
- throw new Exception('Could not sign data');
- }
-
- // Generate JWT
- $encodings[] = base64_encode($sig);
- $jwt = implode('.', $encodings);
- return $jwt;
-
- }
-
-}
-
-
-
-
-/**
- * Oauth 2.0 for web applications
- * @extends GoogleOauth
- *
- */
-class GoogleOauthWeb extends GoogleOauth {
-
- const AUTH_URL = 'https://accounts.google.com/o/oauth2/auth';
- const REVOKE_URL = 'https://accounts.google.com/o/oauth2/revoke';
-
- protected $clientSecret = '';
- protected $redirectUri = '';
-
-
- /**
- * Constructor
- *
- * @access public
- * @param string $clientId (default: '') Client-ID of your web application from the Google APIs console
- * @param string $clientSecret (default: '') Client-Secret of your web application from the Google APIs console
- * @param string $redirectUri (default: '') Redirect URI to your app - must match with an URL provided in the Google APIs console
- */
- public function __construct($clientId='', $clientSecret='', $redirectUri='') {
- $this->clientId = $clientId;
- $this->clientSecret = $clientSecret;
- $this->redirectUri = $redirectUri;
- }
-
- public function setClientSecret($secret) {
- $this->clientSecret = $secret;
- }
-
- public function setRedirectUri($uri) {
- $this->redirectUri = $uri;
- }
-
- /**
- * Build auth url
- * The user has to login with his Google Account and give your app access to the Analytics API
- *
- * @access public
- * @param array $params Custom parameters
- * @return string The auth login-url
- */
- public function buildAuthUrl($params = array()) {
-
- if (!$this->clientId || !$this->redirectUri) {
- throw new Exception('You must provide the clientId and a redirectUri');
- }
-
- $defaults = array(
- 'response_type' => 'code',
- 'client_id' => $this->clientId,
- 'redirect_uri' => $this->redirectUri,
- 'scope' => GoogleOauth::SCOPE_URL,
- 'access_type' => 'offline',
- 'approval_prompt' => 'force',
- );
- $params = array_merge($defaults, $params);
- $url = self::AUTH_URL . '?' . http_build_query($params);
- return $url;
-
- }
-
-
- /**
- * Get the AccessToken in exchange with the code from the auth along with a refreshToken
- *
- * @access public
- * @param mixed $data The code received with GET after auth
- * @return array Array with the following keys: access_token, refresh_token, expires_in
- */
- public function getAccessToken($data=null) {
-
- if (!$this->clientId || !$this->clientSecret || !$this->redirectUri) {
- throw new Exception('You must provide the clientId, clientSecret and a redirectUri');
- }
-
- $params = array(
- 'code' => $data,
- 'client_id' => $this->clientId,
- 'client_secret' => $this->clientSecret,
- 'redirect_uri' => $this->redirectUri,
- 'grant_type' => 'authorization_code',
- );
-
- $auth = Http::curl(GoogleOauth::TOKEN_URL, $params, true);
- return json_decode($auth, $this->assoc);
-
- }
-
-
- /**
- * Get a new accessToken with the refreshToken
- *
- * @access public
- * @param mixed $refreshToken The refreshToken
- * @return array Array with the following keys: access_token, expires_in
- */
- public function refreshAccessToken($refreshToken) {
-
- if (!$this->clientId || !$this->clientSecret) {
- throw new Exception('You must provide the clientId and clientSecret');
- }
-
- $params = array(
- 'client_id' => $this->clientId,
- 'client_secret' => $this->clientSecret,
- 'refresh_token' => $refreshToken,
- 'grant_type' => 'refresh_token',
- );
-
- $auth = Http::curl(GoogleOauth::TOKEN_URL, $params, true);
- return json_decode($auth, $this->assoc);
-
- }
-
-
- /**
- * Revoke access
- *
- * @access public
- * @param mixed $token accessToken or refreshToken
- */
- public function revokeAccess($token) {
-
- $params = array('token' => $token);
- $data = Http::curl(self::REVOKE_URL, $params);
- return json_decode($data, $this->assoc);
- }
-
-
-}
-
-
-
-/**
- * Send data with curl
- *
- */
-class Http {
-
-
- /**
- * Send http requests with curl
- *
- * @access public
- * @static
- * @param mixed $url The url to send data
- * @param array $params (default: array()) Array with key/value pairs to send
- * @param bool $post (default: false) True when sending with POST
- */
- public static function curl($url, $params=array(), $post=false) {
-
- if (empty($url)) return false;
-
- if (!$post && !empty($params)) {
- $url = $url . "?" . http_build_query($params);
- }
- $curl = curl_init($url);
- if ($post) {
- curl_setopt($curl, CURLOPT_POST, true);
- curl_setopt($curl, CURLOPT_POSTFIELDS, $params);
- }
- curl_setopt($curl, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
- curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
- $data = curl_exec($curl);
- $http_code = (int) curl_getinfo($curl, CURLINFO_HTTP_CODE);
- // Add the status code to the json data, useful for error-checking
- $data = preg_replace('/^{/', '{"http_code":'.$http_code.',', $data);
- curl_close($curl);
- return $data;
-
- }
-
-}
-
-?>
diff --git a/Lib/Google/Api/Analytics.php b/Lib/Google/Api/Analytics.php
new file mode 100644
index 0000000..b3aea5e
--- /dev/null
+++ b/Lib/Google/Api/Analytics.php
@@ -0,0 +1,369 @@
+auth = ($auth == 'web') ? new OauthWeb() : new OauthService();
+ $this->defaultQueryParams = array(
+ 'start-date' => date('Y-m-d', strtotime('-1 month')),
+ 'end-date' => date('Y-m-d'),
+ 'metrics' => 'ga:visits',
+ );
+
+ }
+
+ public function __set($key, $value)
+ {
+
+ switch ($key) {
+ case 'auth' :
+ if (($value instanceof GoogleOauth) == false) {
+ throw new Exception('auth needs to be a subclass of GoogleOauth');
+ }
+ $this->auth = $value;
+ break;
+ case 'defaultQueryParams' :
+ $this->setDefaultQueryParams($value);
+ break;
+ default:
+ $this->{$key} = $value;
+ }
+
+ }
+
+ public function setAccessToken($token)
+ {
+ $this->accessToken = $token;
+ }
+
+ public function setAccountId($id)
+ {
+ $this->accountId = $id;
+ }
+
+ public function setDefaultQueryParams(array $params)
+ {
+ $params = array_merge($this->defaultQueryParams, $params);
+ $this->defaultQueryParams = $params;
+ }
+
+ public function returnObjects($bool)
+ {
+ $this->assoc = !$bool;
+ $this->auth->returnObjects($bool);
+ }
+
+ public function query($params = array())
+ {
+ return $this->_query($params);
+ }
+
+ public function getWebProperties()
+ {
+
+ if (!$this->accessToken) {
+ throw new Exception('You must provide an accessToken');
+ }
+
+ $data = Http::curl(self::WEBPROPERTIES_URL, array('access_token' => $this->accessToken));
+ return json_decode($data, $this->assoc);
+
+ }
+
+ public function getProfiles()
+ {
+
+ if (!$this->accessToken) {
+ throw new Exception('You must provide an accessToken');
+ }
+
+ $data = Http::curl(self::PROFILES_URL, array('access_token' => $this->accessToken));
+ return json_decode($data, $this->assoc);
+
+ }
+
+ public function getVisitsByDate($params = array())
+ {
+
+ $defaults = array(
+ 'metrics' => 'ga:visits',
+ 'dimensions' => 'ga:date',
+ );
+ $_params = array_merge($defaults, $params);
+ return $this->_query($_params);
+
+ }
+
+ public function getAudienceStatistics($params = array())
+ {
+
+ $defaults = array(
+ 'metrics' => 'ga:visitors,ga:newVisits,ga:percentNewVisits,ga:visits,ga:bounces,ga:pageviews,ga:visitBounceRate,ga:timeOnSite,ga:avgTimeOnSite',
+ );
+ $_params = array_merge($defaults, $params);
+ return $this->_query($_params);
+
+ }
+
+ public function getVisitsByCountries($params = array())
+ {
+
+ $defaults = array(
+ 'metrics' => 'ga:visits',
+ 'dimensions' => 'ga:country',
+ 'sort' => '-ga:visits',
+ );
+ $_params = array_merge($defaults, $params);
+ return $this->_query($_params);
+
+ }
+
+ public function getVisitsByCities($params = array())
+ {
+
+ $defaults = array(
+ 'metrics' => 'ga:visits',
+ 'dimensions' => 'ga:city',
+ 'sort' => '-ga:visits',
+ );
+ $_params = array_merge($defaults, $params);
+ return $this->_query($_params);
+
+ }
+
+ public function getVisitsByLanguages($params = array())
+ {
+
+ $defaults = array(
+ 'metrics' => 'ga:visits',
+ 'dimensions' => 'ga:language',
+ 'sort' => '-ga:visits',
+ );
+ $_params = array_merge($defaults, $params);
+ return $this->_query($_params);
+
+ }
+
+ public function getVisitsBySystemBrowsers($params = array())
+ {
+
+ $defaults = array(
+ 'metrics' => 'ga:visits',
+ 'dimensions' => 'ga:browser',
+ 'sort' => '-ga:visits',
+ );
+ $_params = array_merge($defaults, $params);
+ return $this->_query($_params);
+
+ }
+
+ public function getVisitsBySystemOs($params = array())
+ {
+
+ $defaults = array(
+ 'metrics' => 'ga:visits',
+ 'dimensions' => 'ga:operatingSystem',
+ 'sort' => '-ga:visits',
+ );
+ $_params = array_merge($defaults, $params);
+ return $this->_query($_params);
+
+
+ }
+
+ public function getVisitsBySystemResolutions($params = array())
+ {
+
+ $defaults = array(
+ 'metrics' => 'ga:visits',
+ 'dimensions' => 'ga:screenResolution',
+ 'sort' => '-ga:visits',
+ );
+ $_params = array_merge($defaults, $params);
+ return $this->_query($_params);
+
+ }
+
+ public function getVisitsByMobileOs($params = array())
+ {
+
+ $defaults = array(
+ 'metrics' => 'ga:visits',
+ 'dimensions' => 'ga:operatingSystem',
+ 'sort' => '-ga:visits',
+ 'segment' => 'gaid::-11',
+ );
+ $_params = array_merge($defaults, $params);
+ return $this->_query($_params);
+
+ }
+
+ public function getVisitsByMobileResolutions($params = array())
+ {
+
+ $defaults = array(
+ 'metrics' => 'ga:visits',
+ 'dimensions' => 'ga:screenResolution',
+ 'sort' => '-ga:visits',
+ 'segment' => 'gaid::-11',
+ );
+ $_params = array_merge($defaults, $params);
+ return $this->_query($_params);
+
+ }
+
+ public function getPageviewsByDate($params = array())
+ {
+
+ $defaults = array(
+ 'metrics' => 'ga:pageviews',
+ 'dimensions' => 'ga:date',
+ );
+ $_params = array_merge($defaults, $params);
+ return $this->_query($_params);
+
+ }
+
+ public function getContentStatistics($params = array())
+ {
+
+ $defaults = array(
+ 'metrics' => 'ga:pageviews,ga:uniquePageviews',
+ );
+ $_params = array_merge($defaults, $params);
+ return $this->_query($_params);
+
+ }
+
+ public function getContentTopPages($params = array())
+ {
+
+ $defaults = array(
+ 'metrics' => 'ga:pageviews',
+ 'dimensions' => 'ga:pagePath',
+ 'sort' => '-ga:pageviews',
+ );
+ $_params = array_merge($defaults, $params);
+ return $this->_query($_params);
+
+ }
+
+ public function getTrafficSources($params = array())
+ {
+
+ $defaults = array(
+ 'metrics' => 'ga:visits',
+ 'dimensions' => 'ga:medium',
+ );
+ $_params = array_merge($defaults, $params);
+ return $this->_query($_params);
+
+ }
+
+ public function getKeywords($params = array())
+ {
+
+ $defaults = array(
+ 'metrics' => 'ga:visits',
+ 'dimensions' => 'ga:keyword',
+ 'sort' => '-ga:visits',
+ );
+ $_params = array_merge($defaults, $params);
+ return $this->_query($_params);
+
+ }
+
+ public function getReferralTraffic($params = array())
+ {
+
+ $defaults = array(
+ 'metrics' => 'ga:visits',
+ 'dimensions' => 'ga:source',
+ 'sort' => '-ga:visits',
+ );
+ $_params = array_merge($defaults, $params);
+ return $this->_query($_params);
+
+ }
+
+
+ protected function _query($params = array())
+ {
+
+ if (!$this->accessToken || !$this->accountId) {
+ throw new Exception('You must provide the accessToken and an accountId');
+ }
+ $_params = array_merge(
+ $this->defaultQueryParams,
+ array('access_token' => $this->accessToken, 'ids' => $this->accountId)
+ );
+ $queryParams = array_merge($_params, $params);
+ $data = Http::curl(self::API_URL, $queryParams);
+ return json_decode($data, $this->assoc);
+
+ }
+
+ public function getOfflineAccessToken($grantCode, $grantType)
+ {
+ $oathWeb = new OauthWeb();
+ $oathWeb->getOfflineAccessToken($grantCode, $grantType);
+ }
+
+ public function prepareToken()
+ {
+ if (isset($_GET['force_oauth'])) {
+ $_SESSION['oauth_access_token'] = null;
+ }
+
+ if (!isset($_SESSION['oauth_access_token']) && !isset($_GET['code'])) {
+ // Go get the url of the authentication page, redirect the client and go get that token!
+ $url = $this->auth->buildAuthUrl();
+ header("Location: " . $url);
+ }
+
+ if (!isset($_SESSION['oauth_access_token']) && isset($_GET['code'])) {
+
+ $auth = $this->auth->getAccessToken($_GET['code']);
+
+ if ($auth['http_code'] == 200) {
+ $accessToken = $auth['access_token'];
+ $refreshToken = $auth['refresh_token'];
+ $tokenExpires = $auth['expires_in'];
+ $tokenCreated = time();
+
+ $_SESSION['oauth_access_token'] = $accessToken;
+
+ if(null != $this->getOfflineAccessToken($accessToken, 'offline')){
+ $_SESSION['oauth_access_token'] = $this->getOfflineAccessToken($accessToken, 'offline');
+ }
+ } else {
+ die("Sorry, something wend wrong retrieving the oAuth tokens");
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/Lib/Google/Api/Http.php b/Lib/Google/Api/Http.php
new file mode 100644
index 0000000..94ad87b
--- /dev/null
+++ b/Lib/Google/Api/Http.php
@@ -0,0 +1,44 @@
+{$key} = $value;
+ }
+
+ public function setClientId($id)
+ {
+ $this->clientId = $id;
+ }
+
+ public function returnObjects($bool)
+ {
+ $this->assoc = !$bool;
+ }
+
+ /**
+ * To be implemented by the subclasses
+ *
+ */
+ public function getAccessToken($data = null)
+ {
+ }
+}
\ No newline at end of file
diff --git a/Lib/Google/Api/OauthService.php b/Lib/Google/Api/OauthService.php
new file mode 100644
index 0000000..3fbe71f
--- /dev/null
+++ b/Lib/Google/Api/OauthService.php
@@ -0,0 +1,103 @@
+clientId = $clientId;
+ $this->email = $email;
+ $this->privateKey = $privateKey;
+ }
+
+
+ public function setEmail($email)
+ {
+ $this->email = $email;
+ }
+
+ public function setPrivateKey($key)
+ {
+ $this->privateKey = $key;
+ }
+
+ public function getAccessToken($data = null)
+ {
+
+ if (!$this->clientId || !$this->email || !$this->privateKey) {
+ throw new Exception('You must provide the clientId, email and a path to your private Key');
+ }
+
+ $jwt = $this->generateSignedJWT();
+
+ $params = array(
+ 'grant_type' => self::GRANT_TYPE,
+ 'assertion' => $jwt,
+ );
+
+ $auth = Http::curl(Oauth::TOKEN_URL, $params, true);
+ return json_decode($auth, $this->assoc);
+
+ }
+
+ protected function generateSignedJWT()
+ {
+ if (!file_exists($this->privateKey) || !is_file($this->privateKey)) {
+ throw new Exception('Private key does not exist');
+ }
+
+ $header = array(
+ 'alg' => 'RS256',
+ 'typ' => 'JWT',
+ );
+
+ $t = time();
+ $params = array(
+ 'iss' => $this->email,
+ 'scope' => Oauth::SCOPE_URL,
+ 'aud' => Oauth::TOKEN_URL,
+ 'exp' => $t + self::MAX_LIFETIME_SECONDS,
+ 'iat' => $t,
+ );
+
+ $encodings = array(
+ base64_encode(json_encode($header)),
+ base64_encode(json_encode($params)),
+ );
+
+ $input = implode('.', $encodings);
+ $certs = array();
+ $pkcs12 = file_get_contents($this->privateKey);
+ if (!openssl_pkcs12_read($pkcs12, $certs, $this->password)) {
+ throw new Exception('Could not parse .p12 file');
+ }
+ if (!isset($certs['pkey'])) {
+ throw new Exception('Could not find private key in .p12 file');
+ }
+ $keyId = openssl_pkey_get_private($certs['pkey']);
+ if (!openssl_sign($input, $sig, $keyId, 'sha256')) {
+ throw new Exception('Could not sign data');
+ }
+
+ $encodings[] = base64_encode($sig);
+ $jwt = implode('.', $encodings);
+ return $jwt;
+
+ }
+
+}
\ No newline at end of file
diff --git a/Lib/Google/Api/OauthWeb.php b/Lib/Google/Api/OauthWeb.php
new file mode 100644
index 0000000..1e75822
--- /dev/null
+++ b/Lib/Google/Api/OauthWeb.php
@@ -0,0 +1,141 @@
+clientId = $clientId;
+ $this->clientSecret = $clientSecret;
+ $this->redirectUri = $redirectUri;
+ }
+
+ public function setClientSecret($secret)
+ {
+ $this->clientSecret = $secret;
+ }
+
+ public function setRedirectUri($uri)
+ {
+ $this->redirectUri = $uri;
+ }
+
+ public function buildAuthUrl($params = array())
+ {
+
+ if (!$this->clientId || !$this->redirectUri) {
+ throw new Exception('You must provide the clientId and a redirectUri');
+ }
+
+ $defaults = array(
+ 'response_type' => 'code',
+ 'client_id' => $this->clientId,
+ 'redirect_uri' => $this->redirectUri,
+ 'scope' => Oauth::SCOPE_URL,
+ 'access_type' => 'offline',
+ 'approval_prompt' => 'force',
+ );
+ $params = array_merge($defaults, $params);
+ $url = self::AUTH_URL . '?' . http_build_query($params);
+ return $url;
+
+ }
+
+ public function getAccessToken($data = null)
+ {
+
+ if (!$this->clientId || !$this->clientSecret || !$this->redirectUri) {
+ throw new Exception('You must provide the clientId, clientSecret and a redirectUri');
+ }
+
+ $params = array(
+ 'code' => $data,
+ 'client_id' => $this->clientId,
+ 'client_secret' => $this->clientSecret,
+ 'redirect_uri' => $this->redirectUri,
+ 'grant_type' => 'authorization_code',
+ );
+
+ $auth = Http::curl(Oauth::TOKEN_URL, $params, true);
+ return json_decode($auth, $this->assoc);
+
+ }
+
+ public function refreshAccessToken($refreshToken)
+ {
+ if (!$this->clientId || !$this->clientSecret) {
+ throw new Exception('You must provide the clientId and clientSecret');
+ }
+
+ $params = array(
+ 'client_id' => $this->clientId,
+ 'client_secret' => $this->clientSecret,
+ 'refresh_token' => $refreshToken,
+ 'grant_type' => 'refresh_token',
+ );
+
+ $auth = Http::curl(Oauth::TOKEN_URL, $params, true);
+ return json_decode($auth, $this->assoc);
+
+ }
+
+ public function revokeAccess($token)
+ {
+ $params = array('token' => $token);
+ $data = Http::curl(self::REVOKE_URL, $params);
+ return json_decode($data, $this->assoc);
+ }
+
+ function getOfflineAccessToken($grantCode, $grantType)
+ {
+ $oauth2token_url = "https://accounts.google.com/o/oauth2/token";
+ $clienttoken_post = array(
+ "client_id" => $this->clientId,
+ "client_secret" => $this->clientSecret
+ );
+
+ if ($grantType === "online") {
+ $clienttoken_post["code"] = $grantCode;
+ $clienttoken_post["redirect_uri"] = 'http://google-analytics.com/oauth2callback';
+ $clienttoken_post["grant_type"] = "authorization_code";
+ }
+
+ if ($grantType === "offline") {
+ $clienttoken_post["refresh_token"] = $grantCode;
+ $clienttoken_post["grant_type"] = "refresh_token";
+ }
+
+ $curl = curl_init($oauth2token_url);
+
+ curl_setopt($curl, CURLOPT_POST, true);
+ curl_setopt($curl, CURLOPT_POSTFIELDS, $clienttoken_post);
+ curl_setopt($curl, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
+ curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
+ curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
+
+ $json_response = curl_exec($curl);
+ curl_close($curl);
+
+ $authObj = json_decode($json_response);
+
+ //if offline access requested and granted, get refresh token
+ if (isset($authObj->refresh_token)) {
+ global $refreshToken;
+ $refreshToken = $authObj->refresh_token;
+ }
+
+ $accessToken = $authObj->access_token;
+ return $accessToken;
+ }
+
+}
\ No newline at end of file
diff --git a/README.md b/README.md
index 0aabbdd..417846e 100755
--- a/README.md
+++ b/README.md
@@ -1,9 +1,15 @@
#Google Analytics API PHP
+Clone this repo and run [composer](http://getcomposer.com). `composer install` then it will autoload the classes and you are done!
+
Simple class to set up Oauth 2.0 with Google and query the Google Analytics API v3 with PHP. Curl is required!
The class supports getting the access tokens for *web applications* and *service accounts* registered in the Google APIs console.
See the documentation for further informations: https://developers.google.com/accounts/docs/OAuth2
+##Install via Composer
+Just add the following line in your `composer.json` and update your dependencies via running composer update command.
+`"shahariaazam/google-analytics-api-php": "dev-master"`
+
##1. Basic Setup
* Create a Project in the Google APIs Console: https://code.google.com/apis/console/
@@ -17,148 +23,54 @@ See the documentation for further informations: https://developers.google.com/ac
Depending on the chosen application type, the setup is slightly different. This section describes both ways independently.
-###2.1 Web applications
+###Web applications
```php
-include('GoogleAnalyticsAPI.class.php');
-
-$ga = new GoogleAnalyticsAPI();
-$ga->auth->setClientId('your_client_id'); // From the APIs console
-$ga->auth->setClientSecret('your_client_secret'); // From the APIs console
-$ga->auth->setRedirectUri('redirect_uri'); // Url to your app, must match one in the APIs console
-
-// Get the Auth-Url
-$url = $ga->auth->buildAuthUrl();
-```
-
-Provide a link to the Auth-Url. The user has to log in with his Google Account, accept that your App will access the Analytics Data. After completing this steps,
-the user will be redirected back to the redirect-uri along with a code.
-This code is needed to get the tokens.
-
-```php
-$code = $_GET['code'];
-$auth = $ga->auth->getAccessToken($code);
-
-// Try to get the AccessToken
-if ($auth['http_code'] == 200) {
- $accessToken = $auth['access_token'];
- $refreshToken = $auth['refresh_token'];
- $tokenExpires = $auth['expires_in'];
- $tokenCreated = time();
-} else {
- // error...
-}
-```
-
-With the accessToken you can query the API for the given time (seconds) in *$tokenExpires*.
-If you need to query the API beyond this time, you should store the refreshToken along with a timestamp in the Database / Session.
-If the accessToken expires, you can get a new one with the refreshToken.
-
-```php
-// Check if the accessToken is expired
-if ((time() - $tokenCreated) >= $tokenExpires) {
- $auth = $ga->auth->refreshAccessToken($refreshToken);
- // Get the accessToken as above and save it into the Database / Session
-}
-```
+auth->setClientId('your_client_id'); // From the APIs console
-$ga->auth->setEmail('your_email_addy'); // From the APIs console
-$ga->auth->setPrivateKey('/super/secure/path/to/your/privatekey.p12'); // Path to the .p12 file
-```
+$ga = new Analytics();
+$ga->auth->setClientId($client_id);
+$ga->auth->setClientSecret($client_secret);
+$ga->auth->setRedirectUri($redirect_uri);
-To query the API, you need to obtain an access token. This token is valid *one hour*, afterwards you'll need to get a new
-token. You can store the token in the database/session.
+$ga->prepareToken();
-```php
-$auth = $ga->auth->getAccessToken();
-
-// Try to get the AccessToken
-if ($auth['http_code'] == 200) {
- $accessToken = $auth['access_token'];
- $tokenExpires = $auth['expires_in'];
- $tokenCreated = time();
-} else {
- // error...
-}
+$ga->setAccessToken($_SESSION['oauth_access_token']);
+$ga->setAccountId($account_id);
```
-##3. Find the Account-ID
-
-Before you can query the API, you need the ID of the Account you want to query the data.
-The ID can be found like this:
-
-```php
-// Set the accessToken and Account-Id
-$ga->setAccessToken($accessToken);
-$ga->setAccountId('ga:xxxxxxx');
-
-// Load profiles
-$profiles = $ga->getProfiles();
-$accounts = array();
-foreach ($profiles['items'] as $item) {
- $id = "ga:{$item['id']}";
- $name = $item['name'];
- $accounts[$id] = $name;
-}
-// Print out the Accounts with Id => Name. Save the Id (array-key) of the account you want to query data.
-// See next chapter how to set the account-id.
-print_r($accounts);
-```
-##4. Query the Google Analytics API
+##Query the Google Analytics API
Once you have a valid accessToken and an Account-ID, you can query the Google Analytics API.
You can set some default Query Parameters that will be executed with every query.
```php
-// Set the accessToken and Account-Id
-$ga->setAccessToken($accessToken);
-$ga->setAccountId('ga:xxxxxxx');
-
-// Set the default params. For example the start/end dates and max-results
$defaults = array(
- 'start-date' => date('Y-m-d', strtotime('-1 month')),
- 'end-date' => date('Y-m-d'),
+ 'start-date' => date('Y-m-d', strtotime('-1 month')),
+ 'end-date' => date('Y-m-d'),
);
$ga->setDefaultQueryParams($defaults);
-// Example1: Get visits by date
$params = array(
- 'metrics' => 'ga:visits',
- 'dimensions' => 'ga:date',
+ 'metrics' => 'ga:visits',
+ 'dimensions' => 'ga:date',
);
$visits = $ga->query($params);
-// Example2: Get visits by country
-$params = array(
- 'metrics' => 'ga:visits',
- 'dimensions' => 'ga:country',
- 'sort' => '-ga:visits',
- 'max-results' => 30,
- 'start-date' => '2013-01-01' //Overwrite this from the defaultQueryParams
-);
-$visitsByCountry = $ga->query($params);
-
-// Example3: Same data as Example1 but with the built in method:
-$visits = $ga->getVisitsByDate();
-
-// Example4: Get visits by Operating Systems and return max. 100 results
-$visitsByOs = $ga->getVisitsBySystemOs(array('max-results' => 100));
-
-// Example5: Get referral traffic
-$referralTraffic = $ga->getReferralTraffic();
-
-// Example6: Get visits by languages
-$visitsByLanguages = $ga->getVisitsByLanguages();
+print "
";
+var_dump($visits);
+print "
";
```
###Metrics & Dimensions Reference:
https://developers.google.com/analytics/devguides/reporting/core/dimsmets
diff --git a/composer.json b/composer.json
new file mode 100644
index 0000000..2641b96
--- /dev/null
+++ b/composer.json
@@ -0,0 +1,15 @@
+{
+ "name": "shahariaazam/google-analytics-api-php",
+ "description": "Simple Google Analytics Reporting API",
+ "homepage": "http://shahariaazam.com",
+ "type": "project",
+ "license": "MIT",
+ "require": {
+ "php": ">=5.4"
+ },
+ "autoload": {
+ "psr-0": {
+ "Google\\Api\\": "Lib"
+ }
+ }
+}
\ No newline at end of file
diff --git a/examples/basics.php b/examples/basics.php
deleted file mode 100644
index 252e41e..0000000
--- a/examples/basics.php
+++ /dev/null
@@ -1,90 +0,0 @@
-';
-
- // From the APIs console
- $client_secret = '';
-
- // Url to your this page, must match the one in the APIs console
- $redirect_uri = '';
-
- // Analytics account id like, 'ga:xxxxxxx'
- $account_id = '';
-
- session_start();
- include('../GoogleAnalyticsAPI.class.php');
-
- $ga = new GoogleAnalyticsAPI();
- $ga->auth->setClientId($client_id);
- $ga->auth->setClientSecret($client_secret);
- $ga->auth->setRedirectUri($redirect_uri);
-
- if (isset($_GET['force_oauth'])) {
- $_SESSION['oauth_access_token'] = null;
- }
-
-
- /*
- * Step 1: Check if we have an oAuth access token in our session
- * If we've got $_GET['code'], move to the next step
- */
- if (!isset($_SESSION['oauth_access_token']) && !isset($_GET['code'])) {
- // Go get the url of the authentication page, redirect the client and go get that token!
- $url = $ga->auth->buildAuthUrl();
- header("Location: ".$url);
- }
-
- /*
- * Step 2: Returning from the Google oAuth page, the access token should be in $_GET['code']
- */
- if (!isset($_SESSION['oauth_access_token']) && isset($_GET['code'])) {
- $auth = $ga->auth->getAccessToken($_GET['code']);
- if ($auth['http_code'] == 200) {
- $accessToken = $auth['access_token'];
- $refreshToken = $auth['refresh_token'];
- $tokenExpires = $auth['expires_in'];
- $tokenCreated = time();
-
- // For simplicity of the example we only store the accessToken
- // If it expires use the refreshToken to get a fresh one
- $_SESSION['oauth_access_token'] = $accessToken;
- } else {
- die("Sorry, something wend wrong retrieving the oAuth tokens");
- }
- }
-
- /*
- * Step 3: Do real stuff!
- * If we're here, we sure we've got an access token
- */
- $ga->setAccessToken($_SESSION['oauth_access_token']);
- $ga->setAccountId($account_id);
-
-
- // Set the default params. For example the start/end dates and max-results
- $defaults = array(
- 'start-date' => date('Y-m-d', strtotime('-1 month')),
- 'end-date' => date('Y-m-d'),
- );
- $ga->setDefaultQueryParams($defaults);
-
- $params = array(
- 'metrics' => 'ga:visits',
- 'dimensions' => 'ga:date',
- );
- $visits = $ga->query($params);
-
- print "";
- var_dump($visits);
- print "
";
diff --git a/index.php b/index.php
new file mode 100644
index 0000000..a7b83b0
--- /dev/null
+++ b/index.php
@@ -0,0 +1,39 @@
+auth->setClientId($client_id);
+$ga->auth->setClientSecret($client_secret);
+$ga->auth->setRedirectUri($redirect_uri);
+
+$ga->prepareToken();
+
+$ga->setAccessToken($_SESSION['oauth_access_token']);
+$ga->setAccountId($account_id);
+
+
+$defaults = array(
+ 'start-date' => date('Y-m-d', strtotime('-1 month')),
+ 'end-date' => date('Y-m-d'),
+);
+$ga->setDefaultQueryParams($defaults);
+
+$params = array(
+ 'metrics' => 'ga:visits',
+ 'dimensions' => 'ga:date',
+);
+$visits = $ga->query($params);
+
+print "";
+var_dump($visits);
+print "
";
diff --git a/settings_backup.php b/settings_backup.php
new file mode 100644
index 0000000..3bf15f1
--- /dev/null
+++ b/settings_backup.php
@@ -0,0 +1,8 @@
+ '',
+ 'clientSecret' => '',
+ 'redirectURI' => '',
+ 'accountID' => ''
+);
\ No newline at end of file