Showing posts with label analytics. Show all posts
Showing posts with label analytics. Show all posts

Monday, April 8, 2013

googla analytics api call details

https://developers.google.com/analytics/resources/articles/gdataCommonQueries 
http://ga-dev-tools.appspot.com/explorer/ 

Site referrals

$ga = $this->service->data_ga->get(
    "ga:34343434",
    $startDate,
    $endDate,
    "ga:visits",
    array(
        "dimensions" => "ga:source",
        'sort' => '-ga:visits',
        'segment' => 'gaid::-8'
    )
);
Search referrals

 $ga = $this->service->data_ga->get(
                $this->accountId,
                $this->startDate,
                $this->endDate,
                "ga:visits",
                array(
                    "dimensions" => "ga:keyword",
                    'sort' => '-ga:visits',
                    "filters" => "ga:medium==organic"
                )
            );
It would seem
ga:medium
ge:visits
does the trick,
  • (none) is "direct traffic
  • organic + cpc is search engine
  • referral is non search engine link
then, the sum of everything else is "campaign"

Keywords from Search Engines

$ga = $this->service->data_ga->get(
    $this->accountId,
    $this->startDate,
    $this->endDate,
    "ga:visits",
    array(
        "dimensions" => "ga:keyword",
        'sort' => '-ga:visits'
    )
);
$ga = $this->service->data_ga->get(
    $this->accountId,
    $this->startDate,
    $this->endDate,
    "ga:visits",
    array(
        "dimensions" => "ga:keyword",
        'sort' => '-ga:visits',
        "filters" => "ga:medium==organic"
    )
);

Search Engines

$ga = $this->service->data_ga->get(
    $this->accountId,
    $this->startDate,
    $this->endDate,
    "ga:visits",
    array(
        "dimensions" => "ga:source",
        'sort' => '-ga:visits',
        "filters" => "ga:medium==cpa,ga:medium==cpc,ga:medium==cpm,ga:medium==cpp,ga:medium==cpv,ga:medium==organic,ga:medium==ppc"
    )
);
Top Landing Pages

$ga = $this->service->data_ga->get(
    $this->accountId,
    $this->startDate,
    $this->endDate,
    "ga:visits",
    array(
        "dimensions" => "ga:landingPagePath",
        'sort' => '-ga:visits'
    )
);
Search referrer details

$ga = $this->service->data_ga->get(
$this->accountId,
$this->startDate,
$this->endDate,
"ga:visits,ga:bounces,ga:visitors,ga:newVisits,ga:timeOnSite,ga:entrances,ga:pageviews,ga:timeOnPage,ga:exits",
array(
"dimensions" => "ga:referralPath",
'sort' => '-ga:visits',
'segment' => 'gaid::-8',
"filters" => "ga:source==".urlencode($referrer)
)
);



 Get segments list

$segments = $analytics->management_segments->listManagementSegments();
Google_Segments Object
(
    [username] => 623644681999-dmg2maloc8obsuiiru0k0fv8no0bouv2@developer.gserviceaccount.com
    [kind] => analytics#segments
    [__itemsType:protected] => Google_Segment
    [__itemsDataType:protected] => array
    [items] => Array
        (
            [0] => Google_Segment Object
                (
                    [definition] => 
                    [kind] => analytics#segment
                    [segmentId] => gaid::-1
                    [created] => 
                    [updated] => 
                    [id] => -1
                    [selfLink] => https://www.googleapis.com/analytics/v3/management/segments/gaid::-1
                    [name] => All Visits
                )

            [1] => Google_Segment Object
                (
                    [definition] => ga:visitorType==New Visitor
                    [kind] => analytics#segment
                    [segmentId] => gaid::-2
                    [created] => 
                    [updated] => 
                    [id] => -2
                    [selfLink] => https://www.googleapis.com/analytics/v3/management/segments/gaid::-2
                    [name] => New Visitors
                )

            [2] => Google_Segment Object
                (
                    [definition] => ga:visitorType==Returning Visitor
                    [kind] => analytics#segment
                    [segmentId] => gaid::-3
                    [created] => 
                    [updated] => 
                    [id] => -3
                    [selfLink] => https://www.googleapis.com/analytics/v3/management/segments/gaid::-3
                    [name] => Returning Visitors
                )

            [3] => Google_Segment Object
                (
                    [definition] => ga:medium==cpa,ga:medium==cpc,ga:medium==cpm,ga:medium==cpp,ga:medium==cpv,ga:medium==ppc
                    [kind] => analytics#segment
                    [segmentId] => gaid::-4
                    [created] => 
                    [updated] => 
                    [id] => -4
                    [selfLink] => https://www.googleapis.com/analytics/v3/management/segments/gaid::-4
                    [name] => Paid Search Traffic
                )

            [4] => Google_Segment Object
                (
                    [definition] => ga:medium==organic
                    [kind] => analytics#segment
                    [segmentId] => gaid::-5
                    [created] => 
                    [updated] => 
                    [id] => -5
                    [selfLink] => https://www.googleapis.com/analytics/v3/management/segments/gaid::-5
                    [name] => Non-paid Search Traffic
                )

            [5] => Google_Segment Object
                (
                    [definition] => ga:medium==cpa,ga:medium==cpc,ga:medium==cpm,ga:medium==cpp,ga:medium==cpv,ga:medium==organic,ga:medium==ppc
                    [kind] => analytics#segment
                    [segmentId] => gaid::-6
                    [created] => 
                    [updated] => 
                    [id] => -6
                    [selfLink] => https://www.googleapis.com/analytics/v3/management/segments/gaid::-6
                    [name] => Search Traffic
                )

            [6] => Google_Segment Object
                (
                    [definition] => ga:medium==(none)
                    [kind] => analytics#segment
                    [segmentId] => gaid::-7
                    [created] => 
                    [updated] => 
                    [id] => -7
                    [selfLink] => https://www.googleapis.com/analytics/v3/management/segments/gaid::-7
                    [name] => Direct Traffic
                )

            [7] => Google_Segment Object
                (
                    [definition] => ga:medium==referral
                    [kind] => analytics#segment
                    [segmentId] => gaid::-8
                    [created] => 
                    [updated] => 
                    [id] => -8
                    [selfLink] => https://www.googleapis.com/analytics/v3/management/segments/gaid::-8
                    [name] => Referral Traffic
                )

            [8] => Google_Segment Object
                (
                    [definition] => ga:goalCompletionsAll>0
                    [kind] => analytics#segment
                    [segmentId] => gaid::-9
                    [created] => 
                    [updated] => 
                    [id] => -9
                    [selfLink] => https://www.googleapis.com/analytics/v3/management/segments/gaid::-9
                    [name] => Visits with Conversions
                )

            [9] => Google_Segment Object
                (
                    [definition] => ga:transactions>0
                    [kind] => analytics#segment
                    [segmentId] => gaid::-10
                    [created] => 
                    [updated] => 
                    [id] => -10
                    [selfLink] => https://www.googleapis.com/analytics/v3/management/segments/gaid::-10
                    [name] => Visits with Transactions
                )

            [10] => Google_Segment Object
                (
                    [definition] => ga:isMobile==Yes
                    [kind] => analytics#segment
                    [segmentId] => gaid::-11
                    [created] => 
                    [updated] => 
                    [id] => -11
                    [selfLink] => https://www.googleapis.com/analytics/v3/management/segments/gaid::-11
                    [name] => Mobile Traffic
                )

            [11] => Google_Segment Object
                (
                    [definition] => ga:bounces==0
                    [kind] => analytics#segment
                    [segmentId] => gaid::-12
                    [created] => 
                    [updated] => 
                    [id] => -12
                    [selfLink] => https://www.googleapis.com/analytics/v3/management/segments/gaid::-12
                    [name] => Non-bounce Visits
                )

            [12] => Google_Segment Object
                (
                    [definition] => ga:isTablet==Yes
                    [kind] => analytics#segment
                    [segmentId] => gaid::-13
                    [created] => 
                    [updated] => 
                    [id] => -13
                    [selfLink] => https://www.googleapis.com/analytics/v3/management/segments/gaid::-13
                    [name] => Tablet traffic
                )

        )

    [itemsPerPage] => 1000
    [previousLink] => 
    [startIndex] => 1
    [nextLink] => 
    [totalResults] => 13
)

Sunday, April 7, 2013

Googple api clients scopes for analytics, calender and more

<?php
global $apiConfig;
$apiConfig = array(
    // True if objects should be returned by the service classes.
    // False if associative arrays should be returned (default behavior).
    'use_objects' => false,
  
    // The application_name is included in the User-Agent HTTP header.
    'application_name' => '',

    // OAuth2 Settings, you can get these keys at https://code.google.com/apis/console
    'oauth2_client_id' => '',
    'oauth2_client_secret' => '',
    'oauth2_redirect_uri' => '',

    // The developer key, you get this at https://code.google.com/apis/console
    'developer_key' => '',
  
    // Site name to show in the Google's OAuth 1 authentication screen.
    'site_name' => 'www.example.org',

    // Which Authentication, Storage and HTTP IO classes to use.
    'authClass'    => 'Google_OAuth2',
    'ioClass'      => 'Google_CurlIO',
    'cacheClass'   => 'Google_FileCache',

    // Don't change these unless you're working against a special development or testing environment.
    'basePath' => 'https://www.googleapis.com',

    // IO Class dependent configuration, you only have to configure the values
    // for the class that was configured as the ioClass above
    'ioFileCache_directory'  =>
        (function_exists('sys_get_temp_dir') ?
            sys_get_temp_dir() . '/Google_Client' :
        '/tmp/Google_Client'),

    // Definition of service specific values like scopes, oauth token URLs, etc
    'services' => array(
      'analytics' => array('scope' => 'https://www.googleapis.com/auth/analytics.readonly'),
      'calendar' => array(
          'scope' => array(
              "https://www.googleapis.com/auth/calendar",
              "https://www.googleapis.com/auth/calendar.readonly",
          )
      ),
      'books' => array('scope' => 'https://www.googleapis.com/auth/books'),
      'latitude' => array(
          'scope' => array(
              'https://www.googleapis.com/auth/latitude.all.best',
              'https://www.googleapis.com/auth/latitude.all.city',
          )
      ),
      'moderator' => array('scope' => 'https://www.googleapis.com/auth/moderator'),
      'oauth2' => array(
          'scope' => array(
              'https://www.googleapis.com/auth/userinfo.profile',
              'https://www.googleapis.com/auth/userinfo.email',
          )
      ),
      'plus' => array('scope' => 
        'https://www.googleapis.com/auth/plus.login',
        'https://www.googleapis.com/auth/plus.me',
        "https://www.googleapis.com/auth/userinfo.email",
        "https://www.googleapis.com/auth/userinfo.profile"
       ),
      'siteVerification' => array('scope' => 'https://www.googleapis.com/auth/siteverification'),
      'tasks' => array('scope' => 'https://www.googleapis.com/auth/tasks'),
      'urlshortener' => array('scope' => 'https://www.googleapis.com/auth/urlshortener')
    )
);

Add/modify/delete users to google analytics account


http://support.google.com/analytics/answer/1009702?hl=en

The features described in this article are only available to Analytics account administrators.
In addition to administrators, you can also add users with read-only access to reports. Those users cannot modify Analytics settings, and you can restrict them to specific profiles.
You can add as many users to an account as you wish.
To add a new user:
  1. Click the Admin tab at the top right of any page in Analytics.
  2. Click the account to which you want to add a user.
  3. Click the Users tab.
  4. Click + New User.
  5. Enter the email address for the user's Google Account. Separate multiple addresses by commas or spaces.
  6. Select User.
  7. From the Available profiles list, select the profiles to which the user should have access. If you do not select a profile, those reports are not available to the user.
  8. Click Add to move these profiles to the Selected profiles list.
  9. Click Save. Any users you created can now log in to Analytics using their Google Account email addresses and passwords.

To modify access for an existing user:
  1. Click the Admin tab at the top right of any page in Analytics.
  2. Click the account to which the user belongs.
  3. Click the Users tab.
  4. Click settings for that user.
  5. If you want to promote the user to an administrator, select Administrator.
  6. If you want to make additional profiles available to the user, select those profiles from the Available profiles list, then click Add.
  7. If you want to remove profiles from the user, select those profiles from the Selected profiles list, the click Remove.
  8. Click Save.

To delete a user:
  1. Click the Admin tab at the top right of any page in Analytics.
  2. Click the account to which the user belongs.
  3. Click the Users tab.
  4. Click delete for the user you want to delete.

Add a new account to google analytics

Add a new account

http://support.google.com/analytics/answer/1009694?hl=en 

To sign up for a Google Analytics account, go to http://www.google.com/analytics and click the Sign up now link. Or, if you are already an AdWords user, you can create a new account via Google Analytics under the Tools and Analysis tab on the AdWords interface.
Creating Additional Analytics Accounts
You can create new Google Analytics accounts even if you are an Administrator for another account.
  1. Sign in to your current Google Analytics account at http://www.google.com/analytics.

  2. Click the Admin tab at the top right of the page.

  3. Above the Profiles tab, at the top of the page, click the All Accounts portion of the link (the full link is: All Accounts > the account to which you're logged in).

  4. Click + New Account.

  5. Select whether you want to track a website or app.

  6. Website: Enter the website name and URL.
    App: Enter the name of the app.

  7. Select an industry category.

  8. Under Data Sharing Settings, select the data-sharing options you want.

  9. Under Reporting Time Zone, select your country or territory from the menu, and select the time zone you want to use.

  10. Enter the name you want to use for the account.

  11. Click Get Tracking ID.

Google APIs Console and service account setup

Google php library

https://code.google.com/p/google-api-php-client/wiki/OAuth2

https://docs.google.com/file/d/0B5nZNPW48dpFMTA5OU1SbUNkMW8/edit?usp=sharing

Overview

OAuth 2.0 is an emerging standard for accessing protected resources on the web. The Google APIs and the google-api-php-client library support OAuth 2.0.

Further Reading

Overview

Use OAuth 2.0 to access to protected data through the Google APIs. Google APIs support a variety of flows designed to support different types of client applications. With all of these flows the client application requests an access token that is associated with only your client application and the owner of the protected data being accessed. The access token is also associated with a limited scope that define the kind of data the your client application has access to (for example "Manage your tasks"). An important goal for OAuth 2.0 is to provide secure and convenient access to the protected data, while minimizing the potential impact if an access token is stolen.

Google APIs Console

Before you can use OAuth 2.0, you must register your application using the Google APIs Console.
Visit the Google API Console to generate your developer key, OAuth2 client id, OAuth2 client secret, and register your OAuth2 redirect uri. Copy their values since your will need to input them in your application.
  • From the "Services" screen, activate access to the API you want to use.
  • Click on "API Access" in the left column
  • Click the button labeled "Create an OAuth2 client ID"
  • Give your application a name and click "Next"
  • Select your "Application type"
  • Click "Create client ID"
  • Click "Edit..." for your new client ID
  • Under the callback URL, enter the fully qualified URL for your PHP application (example http://localhost/googleplus/index.php).

Web Application

Now that you've registered your application with the Google APIs Console, you can now create a web application that uses OAuth 2.0. Here is an example demonstrating how to do authentication with OAuth 2.0 in a web application. The full code for this sample is in the repository.
<?php
require_once 'path/to/Google_Client.php';

$client = new Google_Client();
$client->setClientId('insert_your_oauth2_client_id');
$client->setClientSecret('insert_your_oauth2_client_secret');
$client->setRedirectUri('insert_your_oauth2_redirect_uri');
$client->setDeveloperKey('insert_your_developer_key');
If the user has been redirected back to our page with an authorization code, exchange the code for an access token.
if (isset($_GET['code'])) {
  $client->authenticate();
  $_SESSION['token'] = $client->getAccessToken();
  header('Location: http://' . $_SERVER['HTTP_HOST'] . $_SERVER['PHP_SELF']);
}

Service Accounts

Service Accounts provide certificate-based authentication for server-to-server interactions. This means, for example, that a request from a web application to Google Cloud Storage can be authenticated via a certificate instead of a shared key. Certificates offer better security properties than shared keys and passwords, largely because they are not human-readable or guessable.
Warning: Very few Google APIs currently support Service Accounts. Service accounts are currently supported by the following Google developer services:
  • Google Cloud Storage
  • Google Prediction API
  • Google URL Shortener
  • Google OAuth 2.0 Authorization Server
  • Google BigQuery
To get started:
  1. Visit https://code.google.com/apis/console
  2. Press the down arrow in the left panel (under the Google apis logo).
  3. Press create.
  4. Name your project "Prediction Test Project".
  5. Press create project.
  6. Now a list of APIs should appear. You want to find "Prediction API" and switch that API to "ON".
  7. Select the API Access tab on the left side.
  8. Press "Create OAuth 2.0 Client" and create your client.
  9. Select Service Account as the application type.
  10. Press Download private key.
Now open the examples /prediction/serviceAccount.php sample application in your editor.
  • Make sure you have a recent version of the Google APIs PHP Client downloaded from here.
  • Replace CLIENT_ID with your newly generated clientId. It should look like:
  • xxxxxxxxxxxx-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.apps.googleusercontent.com
  • Replace SERVICE_ACCOUNT_NAME with the email address. It should look like:
  • xxxxxxxxxxxx-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx@developer.gserviceaccount.com
  • Replace KEY_FILE with the path to your private key. Make sure it is saved in a safe place, and readable the sample app.
// Set your client id, service account name, and the path to your private key.
// For more information about obtaining these keys, visit:
// https://developers.google.com/console/help/#service_accounts
const CLIENT_ID = 'insert_your_client_id';
const SERVICE_ACCOUNT_NAME = 'insert_your_service_account_name';
// Make sure you keep your key.p12 file in a secure location, and isn't
// readable by others.
const KEY_FILE = '/super/secret/path/to/key.p12';
// Load the key in PKCS 12 format (you need to download this from the
// Google API Console when the service account was created.
$client = new Google_Client();
...
$key = file_get_contents(KEY_FILE);
$client->setClientId(CLIENT_ID);
$client->setAssertionCredentials(new Google_AssertionCredentials(
  SERVICE_ACCOUNT_NAME,
  array('https://www.googleapis.com/auth/prediction'),
  $key)
);
There is a full sample of using the Prediction API with a Service account.
Learn more about Service accounts from the announcement.


Solving invalid_grant errors

Make sure your server's clock is in sync with NTP.


Here is the URL:
The value which you are referencing is:  54774085
And this is also the value I see in the admin area for "Profile ID"  (54774085)

I had used Service Account for Google Analytics, and get token and get data from google analytics in ruby. It's work for me.
You can try to setup Google Analytics to work with your newly created Service Account:
        -Open Admin section of Google Analytics
        -Click on Users and create a new user in Analytics with the e-mail address provided by the Google API Service Account I had done state above. and i resolve error 403. 

Thursday, February 21, 2013

gapi.class.php gapi class for google analytics data

<?php
/**
 * GAPI - Google Analytics PHP Interface
 * 
 * http://code.google.com/p/gapi-google-analytics-php-interface/
 * 
 * @copyright Stig Manning 2009
 * 
 * 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 <http://www.gnu.org/licenses/>.
 * 
 * @author Stig Manning <stig@sdm.co.nz>
 * @version 1.3
 * 
 */

class gapi
{
  const http_interface = 'auto'; //'auto': autodetect, 'curl' or 'fopen'
  
  const client_login_url = 'https://www.google.com/accounts/ClientLogin';
  const account_data_url = 'https://www.google.com/analytics/feeds/accounts/default';
  const report_data_url = 'https://www.google.com/analytics/feeds/data';
  const interface_name = 'GAPI-1.3';
  const dev_mode = false;
  
  private $auth_token = null;
  private $account_entries = array();
  private $account_root_parameters = array();
  private $report_aggregate_metrics = array();
  private $report_root_parameters = array();
  private $results = array();
  
  /**
   * Constructor function for all new gapi instances
   * 
   * Set up authenticate with Google and get auth_token
   *
   * @param String $email
   * @param String $password
   * @param String $token
   * @return gapi
   */
  public function __construct($email, $password, $token=null)
  {
    if($token !== null)
    {
      $this->auth_token = $token;
    }
    else 
    {
      $this->authenticateUser($email,$password);
    }
  }
  
  /**
   * Return the auth token, used for storing the auth token in the user session
   *
   * @return String
   */
  public function getAuthToken()
  {
    return $this->auth_token;
  }
  
  /**
   * Request account data from Google Analytics
   *
   * @param Int $start_index OPTIONAL: Start index of results
   * @param Int $max_results OPTIONAL: Max results returned
   */
  public function requestAccountData($start_index=1, $max_results=20)
  {
    $response = $this->httpRequest(gapi::account_data_url, array('start-index'=>$start_index,'max-results'=>$max_results), null, $this->generateAuthHeader());
    
    if(substr($response['code'],0,1) == '2')
    {
      return $this->accountObjectMapper($response['body']);
    }
    else 
    {
      throw new Exception('GAPI: Failed to request account data. Error: "' . strip_tags($response['body']) . '"');
    }
  }
  
  /**
   * 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($report_id, $dimensions, $metrics, $sort_metric=null, $filter=null, $start_date=null, $end_date=null, $start_index=1, $max_results=30)
  {
    $parameters = array('ids'=>'ga:' . $report_id);
    
    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))
    {
      $metrics_string = '';
      foreach($metrics as $metric)
      {
        $metrics_string .= ',ga:' . $metric;
      }
      $parameters['metrics'] = substr($metrics_string,1);
    }
    else 
    {
      $parameters['metrics'] = 'ga:'.$metrics;
    }
    
    if($sort_metric==null&&isset($parameters['metrics']))
    {
      $parameters['sort'] = $parameters['metrics'];
    }
    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'));
    }
    
    $parameters['start-date'] = $start_date;
    
    if($end_date==null)
    {
      $end_date=date('Y-m-d');
    }
    
    $parameters['end-date'] = $end_date;
    
    
    $parameters['start-index'] = $start_index;
    $parameters['max-results'] = $max_results;
    
    $parameters['prettyprint'] = gapi::dev_mode ? 'true' : 'false';
    
    $response = $this->httpRequest(gapi::report_data_url, $parameters, null, $this->generateAuthHeader());
    
    //HTTP 2xx
    if(substr($response['code'],0,1) == '2')
    {
      return $this->reportObjectMapper($response['body']);
    }
    else 
    {
      throw new Exception('GAPI: Failed to request report data. Error: "' . strip_tags($response['body']) . '"');
    }
  }

  /**
   * 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 urlencode($filter);
    }
    else 
    {
      return false;
    }
  }
  
  /**
   * Report Account Mapper to convert the XML to array of useful PHP objects
   *
   * @param String $xml_string
   * @return Array of gapiAccountEntry objects
   */
  protected function accountObjectMapper($xml_string)
  {
    $xml = simplexml_load_string($xml_string);
    
    $this->results = null;
    
    $results = array();
    $account_root_parameters = array();
    
    //Load root parameters
    
    $account_root_parameters['updated'] = strval($xml->updated);
    $account_root_parameters['generator'] = strval($xml->generator);
    $account_root_parameters['generatorVersion'] = strval($xml->generator->attributes());
    
    $open_search_results = $xml->children('http://a9.com/-/spec/opensearchrss/1.0/');
    
    foreach($open_search_results as $key => $open_search_result)
    {
      $report_root_parameters[$key] = intval($open_search_result);
    }
    
    $account_root_parameters['startDate'] = strval($google_results->startDate);
    $account_root_parameters['endDate'] = strval($google_results->endDate);
    
    //Load result entries
    
    foreach($xml->entry as $entry)
    {
      $properties = array();
      foreach($entry->children('http://schemas.google.com/analytics/2009')->property as $property)
      {
        $properties[str_replace('ga:','',$property->attributes()->name)] = strval($property->attributes()->value);
      }
      
      $properties['title'] = strval($entry->title);
      $properties['updated'] = strval($entry->updated);
      
      $results[] = new gapiAccountEntry($properties);
    }
    
    $this->account_root_parameters = $account_root_parameters;
    $this->results = $results;
    
    return $results;
  }
  
  
  /**
   * Report Object Mapper to convert the XML to array of useful PHP objects
   *
   * @param String $xml_string
   * @return Array of gapiReportEntry objects
   */
  protected function reportObjectMapper($xml_string)
  {
    $xml = simplexml_load_string($xml_string);
    
    $this->results = null;
    $results = array();
    
    $report_root_parameters = array();
    $report_aggregate_metrics = array();
    
    //Load root parameters
    
    $report_root_parameters['updated'] = strval($xml->updated);
    $report_root_parameters['generator'] = strval($xml->generator);
    $report_root_parameters['generatorVersion'] = strval($xml->generator->attributes());
    
    $open_search_results = $xml->children('http://a9.com/-/spec/opensearchrss/1.0/');
    
    foreach($open_search_results as $key => $open_search_result)
    {
      $report_root_parameters[$key] = intval($open_search_result);
    }
    
    $google_results = $xml->children('http://schemas.google.com/analytics/2009');

    foreach($google_results->dataSource->property as $property_attributes)
    {
      $report_root_parameters[str_replace('ga:','',$property_attributes->attributes()->name)] = strval($property_attributes->attributes()->value);
    }
    
    $report_root_parameters['startDate'] = strval($google_results->startDate);
    $report_root_parameters['endDate'] = strval($google_results->endDate);
    
    //Load result aggregate metrics
    
    foreach($google_results->aggregates->metric as $aggregate_metric)
    {
      $metric_value = strval($aggregate_metric->attributes()->value);
      
      //Check for float, or value with scientific notation
      if(preg_match('/^(\d+\.\d+)|(\d+E\d+)|(\d+.\d+E\d+)$/',$metric_value))
      {
        $report_aggregate_metrics[str_replace('ga:','',$aggregate_metric->attributes()->name)] = floatval($metric_value);
      }
      else
      {
        $report_aggregate_metrics[str_replace('ga:','',$aggregate_metric->attributes()->name)] = intval($metric_value);
      }
    }
    
    //Load result entries
    
    foreach($xml->entry as $entry)
    {
      $metrics = array();
      foreach($entry->children('http://schemas.google.com/analytics/2009')->metric as $metric)
      {
        $metric_value = strval($metric->attributes()->value);
        
        //Check for float, or value with scientific notation
        if(preg_match('/^(\d+\.\d+)|(\d+E\d+)|(\d+.\d+E\d+)$/',$metric_value))
        {
          $metrics[str_replace('ga:','',$metric->attributes()->name)] = floatval($metric_value);
        }
        else
        {
          $metrics[str_replace('ga:','',$metric->attributes()->name)] = intval($metric_value);
        }
      }
      
      $dimensions = array();
      foreach($entry->children('http://schemas.google.com/analytics/2009')->dimension as $dimension)
      {
        $dimensions[str_replace('ga:','',$dimension->attributes()->name)] = strval($dimension->attributes()->value);
      }
      
      $results[] = new gapiReportEntry($metrics,$dimensions);
    }
    
    $this->report_root_parameters = $report_root_parameters;
    $this->report_aggregate_metrics = $report_aggregate_metrics;
    $this->results = $results;
    
    return $results;
  }
  
  /**
   * Authenticate Google Account with Google
   *
   * @param String $email
   * @param String $password
   */
  protected function authenticateUser($email, $password)
  {
    $post_variables = array(
      'accountType' => 'GOOGLE',
      'Email' => $email,
      'Passwd' => $password,
      'source' => gapi::interface_name,
      'service' => 'analytics'
    );
    
    $response = $this->httpRequest(gapi::client_login_url,null,$post_variables);
    
    //Convert newline delimited variables into url format then import to array
    parse_str(str_replace(array("\n","\r\n"),'&',$response['body']),$auth_token);
    
    if(substr($response['code'],0,1) != '2' || !is_array($auth_token) || empty($auth_token['Auth']))
    {
      throw new Exception('GAPI: Failed to authenticate user. Error: "' . strip_tags($response['body']) . '"');
    }
    
    $this->auth_token = $auth_token['Auth'];
  }
  
  /**
   * Generate authentication token header for all requests
   *
   * @return Array
   */
  protected function generateAuthHeader()
  {
    return array('Authorization: GoogleLogin auth=' . $this->auth_token);
  }
  
  /**
   * Perform http request
   * 
   *
   * @param Array $get_variables
   * @param Array $post_variables
   * @param Array $headers
   */
  protected function httpRequest($url, $get_variables=null, $post_variables=null, $headers=null)
  {
    $interface = gapi::http_interface;
    
    if(gapi::http_interface =='auto')
    {
      if(function_exists('curl_exec'))
      {
        $interface = 'curl';
      }
      else 
      {
        $interface = 'fopen';
      }
    }
    
    if($interface == 'curl')
    {
      return $this->curlRequest($url, $get_variables, $post_variables, $headers);
    }
    elseif($interface == 'fopen') 
    {
      return $this->fopenRequest($url, $get_variables, $post_variables, $headers);
    }
    else 
    {
      throw new Exception('Invalid http interface defined. No such interface "' . gapi::http_interface . '"');
    }
  }
  
  /**
   * HTTP request using PHP CURL functions
   * Requires curl library installed and configured for PHP
   * 
   * @param Array $get_variables
   * @param Array $post_variables
   * @param Array $headers
   */
  private function curlRequest($url, $get_variables=null, $post_variables=null, $headers=null)
  {
    $ch = curl_init();
    
    if(is_array($get_variables))
    {
      $get_variables = '?' . str_replace('&amp;','&',urldecode(http_build_query($get_variables)));
    }
    else 
    {
      $get_variables = null;
    }
    
    curl_setopt($ch, CURLOPT_URL, $url . $get_variables);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); //CURL doesn't like google's cert
    
    if(is_array($post_variables))
    {
      curl_setopt($ch, CURLOPT_POST, true);
      curl_setopt($ch, CURLOPT_POSTFIELDS, $post_variables);
    }
    
    if(is_array($headers))
    {
      curl_setopt($ch, CURLOPT_HTTPHEADER,$headers);
    }
    
    $response = curl_exec($ch);
    $code = curl_getinfo($ch,CURLINFO_HTTP_CODE);
    
    curl_close($ch);
    
    return array('body'=>$response,'code'=>$code);
  }
  
  /**
   * HTTP request using native PHP fopen function
   * Requires PHP openSSL
   *
   * @param Array $get_variables
   * @param Array $post_variables
   * @param Array $headers
   */
  private function fopenRequest($url, $get_variables=null, $post_variables=null, $headers=null)
  {
    $http_options = array('method'=>'GET','timeout'=>3);
    
    if(is_array($headers))
    {
      $headers = implode("\r\n",$headers) . "\r\n";
    }
    else 
    {
      $headers = '';
    }
    
    if(is_array($get_variables))
    {
      $get_variables = '?' . str_replace('&amp;','&',urldecode(http_build_query($get_variables)));
    }
    else 
    {
      $get_variables = null;
    }
    
    if(is_array($post_variables))
    {
      $post_variables = str_replace('&amp;','&',urldecode(http_build_query($post_variables)));
      $http_options['method'] = 'POST';
      $headers = "Content-type: application/x-www-form-urlencoded\r\n" . "Content-Length: " . strlen($post_variables) . "\r\n" . $headers;
      $http_options['header'] = $headers;
      $http_options['content'] = $post_variables;
    }
    else 
    {
      $post_variables = '';
      $http_options['header'] = $headers;
    }
    
    $context = stream_context_create(array('http'=>$http_options));
    $response = @file_get_contents($url . $get_variables, null, $context);  
    
    return array('body'=>$response!==false?$response:'Request failed, fopen provides no further information','code'=>$response!==false?'200':'400');
  }
  
  /**
   * 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;
  }
  
  /**
   * Get Results
   *
   * @return Array
   */
  public function getResults()
  {
    if(is_array($this->results))
    {
      return $this->results;
    }
    else 
    {
      return;
    }
  }
  
  
  /**
   * Get an array of the metrics and the matchning
   * aggregate values for the current result
   *
   * @return Array
   */
  public function getMetrics()
  {
    return $this->report_aggregate_metrics;
  }
  
  /**
   * 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];
    }
    
    $aggregate_metric_key = gapi::array_key_exists_nc($name,$this->report_aggregate_metrics);
    
    if($aggregate_metric_key)
    {
      return $this->report_aggregate_metrics[$aggregate_metric_key];
    }

    throw new Exception('No valid root parameter or aggregate metric called "' . $name . '"');
  }
}

/**
 * Class gapiAccountEntry
 * 
 * Storage for individual gapi account entries
 *
 */
class gapiAccountEntry
{
  private $properties = array();
  
  public function __construct($properties)
  {
    $this->properties = $properties;
  }
  
  /**
   * toString function to return the name of the account
   *
   * @return String
   */
  public function __toString()
  {
    if(isset($this->properties['title']))
    {
      return $this->properties['title'];
    }
    else 
    {
      return;
    }
  }
  
  /**
   * Get an associative array of the properties
   * and the matching values for the current result
   *
   * @return Array
   */
  public function getProperties()
  {
    return $this->properties;
  }
  
  /**
   * Call method to find a matching parameter to return
   *
   * @param $name String name of function called
   * @return String
   * @throws Exception if not a valid parameter, 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);
    
    $property_key = gapi::array_key_exists_nc($name,$this->properties);
    
    if($property_key)
    {
      return $this->properties[$property_key];
    }
    
    throw new Exception('No valid property 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;
  }
  
  /**
   * toString function to return the name of the result
   * this is a concatented string of the dimesions chosen
   * 
   * For example:
   * 'Firefox 3.0.10' from browser and browserVersion
   *
   * @return String
   */
  public function __toString()
  {
    if(is_array($this->dimensions))
    {
      return implode(' ',$this->dimensions);
    }
    else 
    {
      return '';
    }
  }
  
  /**
   * Get an associative array of the dimesions
   * and the matching values for the current result
   *
   * @return Array
   */
  public function getDimesions()
  {
    return $this->dimensions;
  }
  
  /**
   * 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];
    }
    
    $dimension_key = gapi::array_key_exists_nc($name,$this->dimensions);
    
    if($dimension_key)
    {
      return $this->dimensions[$dimension_key];
    }

    throw new Exception('No valid metric or dimesion called "' . $name . '"');
  }
}