email = 'user@gmail.com'; $GreqoAnalytics->password = 'password'; $GreqoAnalytics->site_id = '0000001'; // get report $start_uts = time() - ( 3 * $GreqoAnalytics->day_sec ); $stop_uts = time() - ( 2 * $GreqoAnalytics->day_sec ); $REPORT_SUMMARY = $GreqoAnalytics->get_site_summary($start_uts, $stop_uts, $site_id=0); $output = print_r($REPORT_SUMMARY, 1); echo "
$output
"; NOTES To do: update to coordinate with newest Analytics released Google does not provide an official API for Analytics at this time. This class uses the PEAR HTTP_Request class to mimic the browser steps necessary to display a report. This is not necessarily sanctioned by Google and should be used advisedly. ______________________________________________________________________________*/ // Load File of Base Class $base_fname = 'greqo.class.php'; $base_dirpath = ''; require_once($base_dirpath . $base_fname); // GreqoAnalytics /*____________________________________________________________________________*/ class GreqoAnalytics extends Greqo { /* PUBLIC PROPERTIES */ var $debug = 0; var $class_name = __CLASS__; var $oid = ''; var $DS = DIRECTORY_SEPARATOR; var $REPORTS = array(); var $is_logged_in = 0; var $email = ''; var $password = ''; var $site_id = 0; var $GCOOKIE = array(); // Google Analytic Urls var $url_home = 'https://www.google.com/analytics/home/'; var $url_loginbox = 'https://www.google.com/accounts/ServiceLoginBox?service=analytics&nui=1&hl=en-US&continue=http://www.google.com/analytics/home/%3Fet%3Dreset%26hl%3Den-US'; var $url_loginbox_auth = 'https://www.google.com/accounts/ServiceLoginBoxAuth'; var $url_loginbox_auth_cont = 'http://www.google.com/analytics/home/?et=reset&hl=en-US'; var $url_report_request = 'https://www.google.com/analytics/reporting/export?'; var $url_account_request = 'https://www.google.com/analytics/settings/?ns=100&'; var $url_profile_request = 'https://www.google.com/analytics/settings/home?ns=100&scid='; var $url_query_exec = '&user=&vid=2001&ns=10&ss=0&fd=&ft=2&sf=2&sb=1&dow=0&dt=3&dtc=2&xd=1'; var $loginbox_key = 'GA3T'; // Google Analytic Constants var $GA_FMT_XML = 1; var $GA_FMT_CSV = 2; var $GA_CMP_AVG = 'average'; // default cmp value var $GA_CMP_DR = 'date_range'; // compare by date range // other constants var $day_sec = 86400; var $week_sec = 604800; /* PRIVATE PROPERTIES */ var $_filename = ''; var $_dirpath = ''; /* ** MAGIC METHODS ** */ // php4 constructor function GreqoAnalytics($debug=0, $oid=null) { $this->__construct($debug, $oid); register_shutdown_function( array($this, '__destruct') ); } // END constructor // php5 constructor function __construct($debug=0, $oid=null) { // default $this->debug = $debug; $this->oid = ( empty($oid) ) ? $this->class_name : $oid; $this->_set_filename(); $this->_set_dirpath(); // additional code parent::__construct($debug, $oid); // load cacher $this->load_cacher($lifetime=43200); // valid report types served by this class $this->REPORTS = array ( // name => array( GA_name, format, compare) 'visitors' => array('VisitorsOverviewReport', $this->GA_FMT_XML, 1), 'sources' => array('AllSourcesReport', $this->GA_FMT_CSV, 0), 'keywords' => array('KeywordsReport', $this->GA_FMT_CSV, 0), 'content' => array('TopContentReport', $this->GA_FMT_CSV, 0), ); // debug if ( $this->debug ) $this->print_d('debugging is active for oid ' . $this->oid); if ( $this->debug ) $this->print_d('constructor complete for class ' . __CLASS__); } // END constructor // destructor function __destruct() { if ( $this->debug ) $this->print_d("destroying class {$this->class_name} (oid: {$this->oid})"); } // END destructor /* ** PUBLIC METHODS ** */ // method: login function login($force=0) { $logged_in = 0; // return if ( $this->debug ) $this->print_d('login requested'); // get saved session data $this->get_session_data(); // already logged in? if ( $this->is_logged_in && !$force ) { if ( $this->debug ) $this->print_d('already logged in and force (login) flag not set', 'orange'); return 1; } // clear login data $this->logout(); // prep check if ( !$this->_is_login_prepared() ) return 0; // prepare login box request (get loginbox cookie) $this->GreqoClient->setURL($this->url_loginbox); $this->GreqoClient->setMethod(HTTP_REQUEST_METHOD_GET); $this->GreqoResponse = $this->GreqoClient->sendRequest(); // process request $this->GreqoResponse = $this->GreqoClient->sendRequest(); if ( $this->debug ) $this->print_d("Google Response (loginbox: {$this->url_loginbox}):
" . htmlspecialchars($this->GreqoClient->getResponseBody()), '#f66'); if ( PEAR::isError($this->GreqoResponse) ) { $this->_trigger_client_error('login box auth request failed'); return 0; } $GCOOKIE = $this->GreqoClient->getResponseCookies(); $loginbox_body = $this->GreqoClient->getResponseBody(); // error check if ( !ereg('Google Accounts', $loginbox_body) ) { $this->_trigger_request_error('unable to connect to Google Analytics'); return 0; } // get login cookie $loginbox_cookie = $GCOOKIE[$this->loginbox_key]['value']; // prepare login box auth request $this->GreqoClient->setMethod(HTTP_REQUEST_METHOD_POST); $this->GreqoClient->setURL($this->url_loginbox_auth); $this->GreqoClient->addPostData('continue', $this->url_loginbox_auth_cont); $this->GreqoClient->addPostData('service', 'analytics'); $this->GreqoClient->addPostData('nui', '1'); $this->GreqoClient->addPostData('hl', 'en-US'); $this->GreqoClient->addPostData('GA3T', $loginbox_cookie); $this->GreqoClient->addPostData('Email', $this->email); $this->GreqoClient->addPostData('Passwd', $this->password); // process request $this->GreqoResponse = $this->GreqoClient->sendRequest(); if ( $this->debug ) $this->print_d("Google Response (login box auth: {$this->url_loginbox_auth}):
" . htmlspecialchars($this->GreqoClient->getResponseBody()), '#6f6'); if ( PEAR::isError($this->GreqoResponse) ) { $this->_trigger_client_error('login box auth request failed'); return 0; } #$this->_GHEADER = $this->GreqoClient->getResponseHeader(); $this->GCOOKIE = $this->GreqoClient->getResponseCookies(); $loginbox_auth_body = $this->GreqoClient->getResponseBody(); $next_url = ereg_replace(".*logout(); $this->_trigger_request_error('login and password did not match -- check settings'); return 0; } // prepare cookie check request $this->GreqoClient->clearPostData(); $this->GreqoClient->setMethod(HTTP_REQUEST_METHOD_GET); $this->GreqoClient->setURL($next_url); foreach ($this->GCOOKIE as $_CD ) $this->GreqoClient->addCookie($_CD['name'], $_CD['value']); // process request $this->GreqoResponse = $this->GreqoClient->sendRequest(); if ( $this->debug ) $this->print_d("Google Response (cookie check: $next_url):
" . htmlspecialchars($this->GreqoClient->getResponseBody()), '#66f'); $next_url = $this->GreqoClient->getResponseHeader('Location'); if (!$next_url) { $this->logout(); $this->_trigger_request_error('unable to forward to Google Analytics service page (url not returned)'); return 0; } // redirect to service $this->GreqoClient->setURL($next_url); foreach ($this->GCOOKIE as $_CD ) $this->GreqoClient->addCookie($_CD['name'], $_CD['value']); $this->GreqoResponse = $this->GreqoClient->sendRequest(); if ( $this->debug ) $this->print_d("Google Response (service redirect: $next_url):
" . htmlspecialchars($this->GreqoClient->getResponseBody()), '#f66'); if ( PEAR::isError($this->GreqoResponse) ) { $this->logout(); $this->_trigger_client_error('login box auth request failed'); return 0; } $this->is_logged_in = 1; $this->set_session_data(); return 1; } /* REPORT METHODS */ function report_visitors($site_id=null, $start_uts=null, $stop_uts=null) { $greqo_id = $this->REPORTS['visitors']; return $this->get_report($greqo_id, $start_uts, $stop_uts, $this->site_id); } // method: get site summary function get_site_summary($start_uts=0, $stop_uts=0, $site_id=0) { $summary = ''; // return $DATA = $this->get_site_summary_array($start_uts, $stop_uts, $site_id); $summary = $this->_summary_array_to_string($DATA); return $summary; } // END method // method: get site summary function get_site_summary_array($start_uts=0, $stop_uts=0, $site_id=0) { $SUMMARY = array(); // return $REPORT = array(); $META = array(); // defaults $this->site_id = ( !empty($site_id) ) ? $site_id : $this->site_id; if ( empty($start_uts) ) $start_uts = time() - $this->week_sec; if ( empty($stop_uts) ) $stop_uts = time() - $this->day_sec; if ( $this->debug ) $this->print_d("preparing site summary for site #{$this->site_id}"); // Get Reports foreach ( $this->REPORTS as $greqo_id => $ga_id ) { $REPORT[] = $this->get_report($greqo_id, $start_uts, $stop_uts, $this->site_id); } // Organize Reports $SUMMARY = $this->_organize_summary($REPORT); return $SUMMARY; } // end METHOD // method: get report function get_report($greqo_id, $start_uts=0, $stop_uts=0, $site_id=0) { $REPORT = array(); // defaults $this->site_id = ( !empty($site_id) ) ? $site_id : $this->site_id; if ( empty($start_uts) ) $start_uts = time() - $this->week_sec; if ( empty($stop_uts) ) $stop_uts = time() - $this->day_sec; if ( $this->debug ) $this->print_d("preparing report {$greqo_id} for site #{$this->site_id}"); // is this a valid report if ( !isset($this->REPORTS[$greqo_id]) ) { trigger_error("invalid greqo report id [$greqo_id]"); return 0; } // set report variables $id = $this->site_id; $rpt = $this->REPORTS[$greqo_id][0]; $fmt = $this->REPORTS[$greqo_id][1]; $cmp = ( isset($this->REPORTS[$greqo_id][2]) ) ? $this->REPORTS[$greqo_id][2] : 0; $pdr1 = $this->uts_to_date($start_uts); $pdr2 = $this->uts_to_date($stop_uts); // request report if ( !$report_data = $this->request_report_from_google($id, $rpt, $fmt, $pdr1, $pdr2, $cmp) ) { $this->_trigger_error('unable to get report data', E_USER_WARNING); return 0; } // parse report if ( !$REPORT = $this->_parse_report($report_data, $fmt) ) { $this->_trigger_error('unable to parse report data', E_USER_WARNING); return 0; } // add greqo id and cache id $REPORT['greqo_id'] = $greqo_id; // return return $REPORT; } // method: request report from google function request_report_from_google($site_id, $rpt, $fmt=0, $pdr1=0, $pdr2=0, $cmp=0, $trows=10) { $report_data = ''; // return // sanity checks if ( empty($rpt) ) { $this->_trigger_error('must set report name (rpt)', E_USER_WARNING); return 0; } if ( empty($pdr1) ) { $this->_trigger_error('must set date range start (pdr1 : YYMMDD)', E_USER_WARNING); return 0; } if ( empty($pdr2) ) { $this->_trigger_error('must set date range end (pdr2 : YYMMDD)', E_USER_WARNING); return 0; } if ( empty($fmt) ) { $this->_trigger_error('no format set, will set to CSV', E_USER_WARNING); $fmt = $this->GA_FMT_CSV; } // set cache id $cache_id = 'ga_' . $site_id . $rpt . $fmt . $pdr1 . $pdr2 . 'c' . $cmp . 't' . $trows; // check for cache if ( $this->debug ) $this->print_d("looking for cache (id:{$cache_id}) for csv report"); if ( $report_csv_data = $this->GreqoCacher->get($cache_id) ) { if ( $this->debug ) $this->print_d("found cache (id:{$cache_id}) for report", 'green'); return $report_csv_data; } else { if ( $this->debug ) $this->print_d("cache (id:{$cache_id}) not found, will request new report"); } // log in if ( !$this->is_logged_in ) $this->login(); // prep check if ( !$this->_is_report_request_prepared() ) return 0; // prepare compare variables if ( $cmp ) { $uts1 = $this->date_to_uts($pdr1); $uts2 = $this->date_to_uts($pdr2); $pdr_span = $uts2 - $uts1; $cmp_uts2 = $uts1 - $this->day_sec; $cmp_uts1 = $cmp_uts2 - $pdr_span; $cdr1 = $this->uts_to_date($cmp_uts1); $cdr2 = $this->uts_to_date($cmp_uts2); } $cmp_ga = ( $cmp ) ? $this->GA_CMP_DR : $this->GA_CMP_AVG; $url_cdr = ( $cmp ) ? "&cdr={$cdr1}-{$cdr2}" : ''; // set request url $url_query = "fmt={$fmt}&id={$site_id}&pdr={$pdr1}-{$pdr2}{$url_cdr}&cmp={$cmp_ga}&trows={$trows}&rpt={$rpt}"; $request_url = $this->url_report_request . $url_query; // prepare request $this->GreqoClient->setMethod(HTTP_REQUEST_METHOD_GET); $this->GreqoClient->setURL($request_url); // process request if ( $this->debug ) $this->print_d('' . __FUNCTION__ . ' sending request to ' . $request_url . '', 'blue'); $this->GreqoResponse = $this->GreqoClient->sendRequest(); if ( PEAR::isError($this->GreqoResponse) ) { $this->_trigger_client_error('report request failed'); return 0; } // get csv data $report_data = $this->GreqoClient->getResponseBody(); if ( $this->debug ) $this->print_d("
executive_report_csv: \n" . htmlspecialchars($report_data) . '
'); // cache report if ( $this->GreqoCacher->save($report_data, $cache_id) ) { if ( $this->debug ) $this->print_d("report has been cached (id:{$cache_id}) for {$this->GreqoCacher->_lifeTime} s", 'green'); } else { if ( $this->debug ) $this->print_d("unable to cache (id:{$cache_id})", 'yellow'); } return $report_data; } // END method // method: request account list function request_account_list() { // cue: if Google changes this, this method will fail. So update as needed. $cue = 'name="account_selector"'; $ACCOUNT = array(); // return // log in if ( !$this->is_logged_in ) $this->login(); if ( !$this->is_logged_in ) { return 0; } // prep check if ( !$this->_is_login_prepared() ) return 0; // set request url $request_url = $this->url_account_request; // prepare request $this->GreqoClient->setMethod(HTTP_REQUEST_METHOD_GET); $this->GreqoClient->setURL($request_url); // process request if ( $this->debug ) $this->print_d('' . __FUNCTION__ . ' sending account list request to ' . $request_url . '', 'blue'); $this->GreqoResponse = $this->GreqoClient->sendRequest(); if ( PEAR::isError($this->GreqoResponse) ) { $this->_trigger_client_error('account list request failed'); return 0; } // parse body $response = $this->GreqoClient->getResponseBody(); if ( $this->debug ) $this->print_d("
account list request response: \n" . htmlspecialchars($response) . '
'); // unexpected response if ( !strpos($response, $cue) ) { $this->_trigger_error("unexpected response: parse cue missing [$cue]"); return 0; } // parse list (credit: tantan_GoogleAnalytics) $response = substr($response, strpos($response, $cue)); $response = substr($response, 0, strpos($response, "")); preg_match_all("/(.*)<\/option>/isU", $response, $MATCH); // package data foreach ( $MATCH[1] as $n => $account_id ) { $account_name = ( isset($MATCH[2][$n]) ) ? $MATCH[2][$n] : 0; if ( !empty($account_id) && !empty($account_name) ) $ACCOUNT[$account_name] = $account_id; } return $ACCOUNT; } // END method // method: request profile list function request_profile_list($account_id=null) { // cue: if Google changes this, this method will fail. So update as needed. $parse_cue = 'id="account_profile_selector"'; $PROFILE = array(); // return // log in if ( !$this->is_logged_in ) $this->login(); if ( !$this->is_logged_in ) { return 0; } // prep check if ( !$this->_is_login_prepared() ) return 0; // set request url $request_url = $this->url_profile_request . $account_id; // prepare request $this->GreqoClient->setMethod(HTTP_REQUEST_METHOD_GET); $this->GreqoClient->setURL($request_url); // process request if ( $this->debug ) $this->print_d('' . __FUNCTION__ . ' sending profile list request to ' . $request_url . '', 'blue'); $this->GreqoResponse = $this->GreqoClient->sendRequest(); if ( PEAR::isError($this->GreqoResponse) ) { $this->_trigger_client_error('profile list request failed'); return 0; } // parse body $response = $this->GreqoClient->getResponseBody(); if ( $this->debug ) $this->print_d("
profile list request response: \n" . htmlspecialchars($response) . '
'); // unexpected response if ( !strpos($response, $parse_cue) ) { $this->_trigger_error('unexpected response: parse cue missing [$parse_cue]'); return 0; } // parse list (credit: tantan_GoogleAnalytics) $response = substr($response, strpos($response, $parse_cue)); $response = substr($response, 0, strpos($response, "")); preg_match_all("/(.*)<\/option>/isU", $response, $MATCH); // package data foreach ( $MATCH[1] as $n => $profile_id ) { $profile_name = ( isset($MATCH[2][$n]) ) ? $MATCH[2][$n] : 0; if ( !empty($profile_id) && !empty($profile_name) ) $PROFILE[$profile_name] = $profile_id; } return $PROFILE; } // END method // method: convert unix timestamp to GA date format function uts_to_date($uts) { $date = ''; if ( !$date = date('Ymd', $uts) ) $this->_trigger_error("invalid uts: $uts"); return $date; } // END method // method: convert GA date format to unix timestamp function date_to_uts($date) { $uts = 0; if ( !$uts = strtotime($date) ) $this->_trigger_error("invalid date: $date"); return $uts; } // END method // method: set report cache lifetime function set_report_cache_lifetime($secs) { $this->load_cacher($secs); } // END method // method: get session data function get_session_data() { // initialize session if ( !session_id() ) session_start(); // sanity check if ( empty($_SESSION[$this->oid]) ) return 0; // is this the same user if ( isset($this->email) && ( $_SESSION[$this->oid]['email'] != $this->email ) ) { $this->clear_session_data(); return 0; } // get session data $this->email = $_SESSION[$this->oid]['email']; $this->is_logged_in = isset($_SESSION[$this->oid]['is_logged_in']) ? $_SESSION[$this->oid]['is_logged_in'] : 0; $this->GCOOKIE = $_SESSION[$this->oid]['COOKIES']; // set cookies if ( is_array($this->GCOOKIE) ) { foreach ( $this->GCOOKIE as $_CD ) $this->GreqoClient->addCookie($_CD['name'], $_CD['value']); } return 1; } // END method // method: set session data function set_session_data() { // initialize session if ( !session_id() ) session_start(); $_SESSION[$this->oid] = array(); // sanity check if ( !$this->is_logged_in ) { trigger_error("not logged in: session data should be set only after logging in", E_USER_WARNING); return 0; } $_SESSION[$this->oid]['email'] = $this->email; $_SESSION[$this->oid]['is_logged_in'] = $this->is_logged_in; $_SESSION[$this->oid]['COOKIES'] = $this->GCOOKIE; return 1; } // END method // method: set session data function clear_session_data() { // initialize session if ( !session_id() ) session_start(); $_SESSION[$this->oid] = null; return; } // END method // method: logout function logout() { $this->is_logged_in = 0; $this->clear_session_data(); } // END method /* ** PRIVATE METHODS ** */ // method: summary array to string function _summary_array_to_string($DATA) { $string = ''; // return $sum_keywords = ''; $sum_sources = ''; $sum_content = ''; // prepare data $name = $DATA['META']['profile_name']; $dates = $DATA['META']['date_range']; $cf_dates = ( !empty($DATA['META']['date_range']) ) ? $DATA['META']['date_range'] : ''; $tv = $DATA['VISITORS']['visits']['value']; $uv = $DATA['VISITORS']['unique_visits']['value']; $pv = $DATA['VISITORS']['pageviews']['value']; $tvy = !empty($cf_dates) ? "({$DATA['VISITORS']['visits']['submessage']} / {$DATA['VISITORS']['visits']['delta']})" : ''; $uvy = !empty($cf_dates) ? "({$DATA['VISITORS']['unique_visits']['submessage']} / {$DATA['VISITORS']['unique_visits']['delta']})" : ''; $pvy = !empty($cf_dates) ? "({$DATA['VISITORS']['pageviews']['submessage']} / {$DATA['VISITORS']['pageviews']['delta']})" : ''; // sources if ( !empty($DATA['SOURCES']['RECORDS']) ) { $sum_sources .= "source/medium : visits | pg/v | time (s) \n"; foreach ( $DATA['SOURCES']['RECORDS'] as $i => $_REC ) { $n = $i + 1; $sum_sources .= "{$n}. {$_REC['Source/Medium']} : {$_REC['Visits']} | {$_REC['Pages/Visit']} | {$_REC['Avg. Time on Site']} \n"; } } // keywords if ( !empty($DATA['KEYWORDS']['RECORDS']) ) { $sum_keywords .= "keywords : visits \n"; foreach ( $DATA['KEYWORDS']['RECORDS'] as $i => $_REC ) { $n = $i + 1; $sum_keywords .= "{$n}. {$_REC['Keyword']} : {$_REC['Visits']}\n"; } } // content if ( !empty($DATA['CONTENT']['RECORDS']) ) { $sum_content .= "page (url) : views | unique | time (s) \n"; foreach ( $DATA['CONTENT']['RECORDS'] as $i => $_REC ) { $n = $i + 1; $sum_content .= "{$n}. {$_REC['Page']} : {$_REC['Pageviews']} | {$_REC['Unique Pageviews']} | {$_REC['Time on Page']} \n"; } } // build $string = <<debug ) $this->print_d('organizing summar of array: ' . $this->print_r($REPORT)); // Meta Data $cf_dates = isset($REPORT[0]['CompareDateRange']) ? $REPORT[0]['CompareDateRange'] : ''; $SUMMARY['META'] = array ( 'profile_name' => $REPORT[0]['ProfileName'], 'site_id' => $this->site_id, 'date_range' => $REPORT[0]['PrimaryDateRange'], 'date_compare' => $cf_dates, 'date_range_ymd' => $REPORT[1]['dates'], 'report_date' => date('Y-m-d H:i:s'), 'uts' => time(), ); // Visitor Data $SUMMARY['VISITORS'] = array ( 'greqo_id' => $REPORT[0]['greqo_id'], 'report_name' => $REPORT[0]['Name'], #'cache_id' => $REPORT[0]['cache_id'], 'visits' => $REPORT[0]['Visits'], 'unique_visits' => $REPORT[0]['Absolute Unique Visitors'], 'pageviews' => $REPORT[0]['Pageviews'], 'pageview_per_visit' => $REPORT[0]['Average Pageviews'], 'bounce_rate' => $REPORT[0]['Bounce Rate'], 'new_visits' => $REPORT[0]['New Visits'], 'time_per_visit' => $REPORT[0]['Time on Site'], ); // Other Reports for ( $i=1; $i $REPORT[$i]['greqo_id'], 'report_name' => $REPORT[$i]['name'], #'cache_id' => $REPORT[$i]['cache_id'], 'num_cols' => $REPORT[$i]['SECTION'][1]['num_cols'], 'num_records' => $REPORT[$i]['SECTION'][1]['num_records'], 'RECORDS' => $REPORT[$i]['SECTION'][1]['RECORD'], ); } return $SUMMARY; } // END method // method: parse report function _parse_report($report_data, $format) { $REPORT = array(); // return if ( $format == $this->GA_FMT_XML ) { $REPORT = $this->_quick_parse_report_xml($report_data); } elseif ( $format == $this->GA_FMT_CSV ) { $REPORT = $this->_parse_report_csv($report_data); } else { $this->_trigger_error("unknown format [$format]"); return 0; } return $REPORT; } // END method // method: parse report csv (v.2) function _parse_report_csv($raw_csv) { $REPORT = array(); // return $_FLAG['parsed_header'] = 0; if ( $this->debug ) $this->print_d('parsing report'); // get sections $_SECTION = explode("\n\n", $raw_csv); if ( $this->debug ) $this->print_d('parsed report into ' . count($_SECTION) . ' sections'); // get header $_LINES = explode("\n", $_SECTION[0]); foreach ( $_LINES as $line ) { if ( !empty($line) && ( strpos($line, '# -') === false ) ) $_HEADER[] = $line; } $REPORT['profile'] = $_HEADER[0]; $REPORT['name'] = $_HEADER[1]; // get dates if ( $match = preg_match_all('|"([^"]+)"|', $_HEADER[2], $_DATES) ) { foreach ( $_DATES[1] as $_date ) $_YMD[] = date('Ymd', strtotime($_date)); $REPORT['dates'] = "{$_YMD[0]} - {$_YMD[1]}"; } else { $REPORT['dates'] = $_HEADER[2]; } // parse remainings sections for ( $i=1; $i_parse_report_section($_SECTION[$i]); } return $REPORT; } // END method // method: parse report section function _parse_report_section($raw_section_csv) { $SECTION = array(); // return $_LINES = explode("\n", $raw_section_csv); $dcolor = '#999'; if ( $this->debug ) $this->print_d("parsing report section:
$raw_section_csv
"); foreach ( $_LINES as $line ) { // trim line $line = trim($line); if ( $this->debug ) $this->print_d('
parsing line: ' . htmlspecialchars($line), '#996'); // ignore empty or comment lines if ( empty($line) || ( strpos($line, '#-') !== false ) || ( strpos($line, '# -') !== false ) ) { if ( $this->debug ) $this->print_d('line id\'d as empty', $dcolor); continue; } // header rows elseif ( $line{0} == '#' ) { if ( $this->debug ) $this->print_d('line id\'d as header', $dcolor); // package *last* dataset if ( !empty($dataset_title) ) { $DATASET[] = array ( 'title' => $dataset_title, 'num_cols' => count($COLUMN), 'num_records' => count($RECORD), 'COLUMN' => $COLUMN, 'RECORD' => $RECORD ); if ( $this->debug ) $this->print_d("packaging dataset '$dataset_title'"); } // init new dataset $dataset_title = trim(substr($line, 2)); $COLUMN = array(); $RECORD = array(); // we don't care about graphs if ( $dataset_title == 'Graph' ) { if ( $this->debug ) $this->print_d('graph section are ignored and return \'graph\'', 'magenta'); return 'graph'; } } // column row elseif ( empty($COLUMN) ) { if ( $this->debug ) $this->print_d('line id\'d as column'); // get column names $COLUMN = explode(',', $line); foreach ($COLUMN as $ck => $cv) $COLUMN[$ck] = trim($cv); } // record row else { if ( $this->debug ) $this->print_d('line id\'d as record'); $_NEW_RECORD = array(); $_LINE_SEG = explode(',', $line); foreach ( $_LINE_SEG as $i => $value ) $_NEW_RECORD['value'.$i] = trim($value); $RECORD[] = $_NEW_RECORD; if ( $this->debug ) $this->print_d('record: ' . print_r($_NEW_RECORD)); } } // package the final dataset $DATASET[] = array ( 'title' => $dataset_title, 'num_cols' => count($COLUMN), 'num_records' => count($RECORD), 'COLUMN' => $COLUMN, 'RECORD' => $RECORD ); // package datasets foreach ( $DATASET as $n => $_SET ) { $SECTION['title'] = $_SET['title']; $SECTION['num_cols'] = $_SET['num_cols']; $SECTION['num_records'] = $_SET['num_records']; $SECTION['COLUMN'] = $_SET['COLUMN']; $SECTION['RECORD'] = array(); // repackage records if ( empty($_SET['RECORD']) ) { $SECTION['RECORD'] = 0; } else { foreach ( $_SET['RECORD'] as $i => $_COLS ) { $SECTION['RECORD'][$i] = array(); for ( $j=0; $jdebug ) $this->print_d($this->print_r($SECTION)); return $SECTION; } // END method // method: quick parse report xml function _quick_parse_report_xml($xml_string) { $DATA = array(); // control array $TITLE_METAKEY = array('Name','ProfileName','PrimaryDateRange','CompareDateRange'); // regex $_REGEX['title'] = '|]+>(.*)|iU'; $_REGEX['title_data'] = '|<([^>]+)>(.*)]+>|iU'; $_REGEX['item_summary'] = '|]+>(.*)|iU'; $_REGEX['key'] = '|(.*)|iU'; $_REGEX['value'] = '|(.*)|iU'; $_REGEX['submessage'] = '|(.*)|iU'; $_REGEX['delta'] = '|(.*)|iU'; // parse title if ( !preg_match_all($_REGEX['title'], $xml_string, $TITLE) ) trigger_error('unable to parse title'); if ( $this->debug ) $this->_dump_array($TITLE); if ( !empty($TITLE) ) { $xml_title = $TITLE[1][0]; preg_match_all($_REGEX['title_data'], $xml_title, $TITLE_DATA); foreach ( $TITLE_DATA[1] as $i => $_metakey ) { if ( in_array($_metakey,$TITLE_METAKEY) ) { $DATA[$_metakey] = $TITLE_DATA[2][$i]; } } } if ( $this->debug ) $this->_dump_array($TITLE_DATA); // parse item summaries $matched = preg_match_all($_REGEX['item_summary'], $xml_string, $ITEM_XML); if ( $this->debug ) $this->_dump_array($ITEM_XML); if ( !$matched ) return $DATA; foreach ( $ITEM_XML[1] as $_xml ) { if ( $this->debug ) $this->print_d('parsing : ' . htmlspecialchars($_xml)); $key = $val = $sub = $delta = ''; if ( preg_match($_REGEX['key'], $_xml, $_KEY) ) $key = strip_tags($_KEY[0]); else trigger_error('unable to parse item key'); if ( preg_match($_REGEX['value'], $_xml, $_VAL) ) $val = strip_tags($_VAL[0]); else trigger_error('unable to parse item value'); // compare values if ( preg_match($_REGEX['submessage'], $_xml, $_SUB) ) $sub = strip_tags($_SUB[0]); if ( preg_match($_REGEX['delta'], $_xml, $_DEL) ) $delta = strip_tags($_DEL[0]); if ( !empty($key) ) { $DATA[$key]['value'] = $val; if ( !empty($sub) ) $DATA[$key]['submessage'] = $sub; if ( !empty($delta) ) $DATA[$key]['delta'] = $delta; } } if ( $this->debug ) $this->_dump_array($DATA); return $DATA; } // END method // method: is report request prepared function _is_report_request_prepared() { if ( !$this->_is_login_prepared() ) return 0; if ( !$this->is_logged_in ) { trigger_error('must login before requesting a report', E_USER_WARNING); return 0; } if ( empty($this->site_id) ) { trigger_error('site id must be set (login and check profile links if unsure)', E_USER_WARNING); return 0; } return 1; } // END method // method: trigger error function _trigger_error($message) { $this->GreqoClient->_postData['Passwd'] = $this->password = '**scrubbed**'; trigger_error('greqo analytics error: ' . $message, E_USER_WARNING); if ( $this->debug ) { $this->print_d('

Analytics Object

' . $this->print_r($this), 'magenta'); } } // END method // method: dump array function _dump_array($ARRAY) { $dump = htmlspecialchars(print_r($ARRAY,1)); $this->print_d("
$dump
", '#33c'); return; } // END method function _set_filename() { $this->_filename = basename(__FILE__); } function _set_dirpath() { $this->_dirpath = dirname(__FILE__) . $this->DS; } } // end class /*____________________________________________________________________________*/ ?>