0

I use Measurement Protocol Parameter Reference in PHP to setup Google Analytics using PHP. For now all works fine only I can't figure out how to setup Timing.

In my GA dashboard session duration not work and I need to add that.

Here is reference of TIMING and I don't understand how to setup that.

Do I need to setup some sessions or I need to read __utma, __utmb, __utmc... cookies?

This is all in the initial stage but it works perfectly.

/**
 * Generic Server-Side Google Analytics PHP Client
 *
 * PHP version 5
 *
 * @category   Google Analytics
 * @author     Ivijan-Stefan Stipić <ivijan.stefan@gmail.com>
 * @copyright  2015 CreativForm
 * @license    http://www.php.net/license/3_01.txt  PHP License 3.01
 * @version    1.4
 * @link       http://creativform.com/
 */
class cfSSGA
{
    // Google Analysis Measurement Protocol Parameter URL
    private $analyticsURL = 'https://ssl.google-analytics.com/collect?payload_data&{URL-DATA}';
    // Default Options
    private $option=array(
            // Google Analysis ID xx-xxxxxxxx-x
            'gaID'      =>  'xx-xxxxxxxx-x',
            // 'pageview', 'screenview', 'event', 'transaction', 'item', 'social', 'exception', 'timing'
            'hitType'   =>  'pageview',
            // page URL
            'pageURL'   =>  NULL,
            // page Title
            'pageTitle' =>  NULL,
            // page Encoding
            'pageEncoding'  =>  'UTF-8',
        );
    function __construct($options)
    {
        $this->__session_start();
        if(function_exists("array_replace") && version_compare(phpversion(), '5.3.0', '>='))
            $this->option=(object)array_replace($this->option, $options); // (PHP 5 >= 5.3.0)
        else 
            $this->option=(object)array_merge($this->option, $options); // (PHP 5 < 5.3.0)
        // Send data to GA
        $this->sendData();
    }
    private function sendData(){        
        $aux = $this->__utmz();

        $data = array(
            /* Page Tracking Setup  */
            'v'     =>  1,                      // Version.
            'tid'   =>  $this->option->gaID,    // Tracking ID / Property ID.
            'cid'   =>  $this->ParseOrCreateAnalyticsCookie(),  // Anonymous Client ID.
            'uid'   =>  $this->__userID(),      // Anonymous User ID.
            't'     =>  $this->option->hitType, // Pageview hit type.
            'dh'    =>  $_SERVER["HTTP_HOST"],  // Document hostname.

            'z'     =>  mt_rand(1000000000, 9999999999),    // hash URL

            'dp'    =>  (is_null($this->option->pageURL)?@$_SERVER["REQUEST_URI"]:$this->option->pageURL),      // Page.
            'dt'    =>  (is_null($this->option->pageTitle)?@$_SERVER["REQUEST_URI"]:$this->option->pageTitle),  // Title.
            'dl'    =>  "https://".$_SERVER["HTTP_HOST"].$_SERVER["REQUEST_URI"],   // Send full URL

            /* Using a Proxy Server */
            'uip'   =>  $this->ip(),                    // IP address override.
            'ua'    =>  $_SERVER['HTTP_USER_AGENT'],    // User agent override.

            // Traffic Source
            'cn'    =>  $aux->utmccn,
            'cs'    =>  $aux->utmcsr,
            'cm'    =>  $aux->utmcmd,
            'ck'    =>  $aux->utmctr,
            'dr'    =>  $_SERVER['HTTP_REFERER'],

            // Page Encoding
            'de'=>$this->option->pageEncoding,
        );
        if(isset($_SERVER["HTTP_ACCEPT_LANGUAGE"])) $data['ul']=strtolower(substr($_SERVER["HTTP_ACCEPT_LANGUAGE"],0,5)); // set language

        // AdWords tracking
        if(!empty($aux->utmgclid)){
            $data['gclid']=$aux->utmgclid;
        }
        if(!empty($aux->utmgclid)){
            $data['cc']=$aux->utmcct;
        }
        if(!empty($aux->utmgclid)){
            $data['ci']=$aux->utmcid;
        }

        // send GET data
        $url=array();
        $data=array_map("trim", $data);
        foreach($data as $get=>$val)
        {
            if(!is_null($val) && !empty($val))
            $url[]=$get.'='.str_replace('+','%20',urlencode($val));
        }
        $getString=join("&",$url);
        $getString=str_replace("{URL-DATA}",$getString,$this->analyticsURL);

        ## DEBUG
        ob_start();
        var_dump($getString);
        $str=ob_get_clean();

        echo '<!-- 
        '.$str.'
        -->';
        ###########

        file_get_contents($getString);
    }
    // read __utmz cookie - Traffic Source
    private function __utmz(){
        // Default ID's of Traffic Source Cookie
        $trafficSourceDefault = array(
            'utmcid'    =>  false,          // lookup table id
            'utmcsr'    =>  $_SERVER['HTTP_REFERER'],   // campaign source
            'utmgclid'  =>  false,          // google ad click id
            'utmccn'    =>  '(organic)',    // campaign name
            'utmcmd'    =>  'organic',  // campaign medium
            'utmctr'    =>  '(not set)',    // keywords
            'utmcct'    =>  false,          // ad content description
        );
        $trafficSource=array();
        $all_data=array();
        if(isset($_COOKIE['__utmz']) || isset($_GET['__utmz'])){
            $cookie = ((isset($_GET['__utmz']) && !empty($_GET['__utmz'])) ? $_GET['__utmz'] : $_COOKIE['__utmz']);
            // Parse __utmz cookie
            list($domain_hash, $timestamp, $session_number, $campaign_numer, $campaign_data) = preg_split('[\.]', $cookie, 5);
            // Parse the campaign data
            $campaign_data = parse_str(str_replace("|", "&", $campaign_data));
            // construct all
            if(isset($utmcid)&&!empty($utmcid))         $all_data['utmcid']=$utmcid;
            if(isset($utmcsr)&&!empty($utmcsr))         $all_data['utmcsr']=(strtolower($utmcmd)=='organic'?"https://".$_SERVER["HTTP_HOST"].$_SERVER["REQUEST_URI"]:$utmcsr);
            if(isset($utmgclid)&&!empty($utmgclid))     $all_data['utmgclid']=$utmgclid;
            if(isset($utmccn)&&!empty($utmccn))         $all_data['utmccn']=$utmccn;
            if(isset($utmcmd)&&!empty($utmcmd))         $all_data['utmcmd']=$utmcmd;
            if(isset($utmctr)&&!empty($utmctr))         $all_data['utmctr']=$utmctr;
            if(isset($utmcct)&&!empty($utmcct))         $all_data['utmcct']=$utmcct;

            if(str_replace(array("http","https",":","/","www."),"",$_SERVER['HTTP_REFERER'])==$_SERVER["HTTP_HOST"]){
                unset($all_data['utmccn']);
                unset($all_data['utmcsr']);
                unset($all_data['utmcmd']);
                $all_data['utmccn']='(organic)';
                $all_data['utmcsr']=$_SERVER["HTTP_HOST"];
                $all_data['utmcmd']='organic';
            }
        }

        if(function_exists("array_replace") && version_compare(phpversion(), '5.3.0', '>='))
            $data=(object)array_replace($trafficSourceDefault, $all_data); // (PHP 5 >= 5.3.0)
        else 
            $data=(object)array_merge($trafficSourceDefault, $all_data); // (PHP 5 < 5.3.0)
        return $data;
    }
    // Gets the current Analytics session identifier or create a new one if it does not exist
    private function ParseOrCreateAnalyticsCookie(){
        if (isset($_COOKIE['_ga']) && !empty($_COOKIE['_ga']))
        {
            // An analytics cookie is found
            list($version, $domainDepth, $cid1, $cid2) = preg_split('[\.]', $_COOKIE["_ga"], 4);
            $contents = array(
                'version' => $version,
                'domainDepth' => $domainDepth,
                'cid' => $cid1.'.'.$cid2
            );
            $cid    =   $contents['cid'];
        }
        else
        {
            // no analytics cookie is found. Create a new one
            $cid1 = mt_rand(0, 2147483647);
            $cid2 = mt_rand(0, 2147483647);

            $cid = $cid1 . '.' . $cid2;
            setcookie('_ga', 'GA1.2.' . $cid, (time() + (60 * 60 * 24 * 365 * 2)), '/');
        }
        return $cid;
    }
    // GET IP address
    private function ip(){
        if(isset($_SERVER['HTTP_CLIENT_IP']) && filter_var($_SERVER['HTTP_CLIENT_IP'], FILTER_VALIDATE_IP))
            return $_SERVER['HTTP_CLIENT_IP'];
        elseif(isset($_SERVER['HTTP_X_FORWARDED_FOR']) && filter_var($_SERVER['HTTP_X_FORWARDED_FOR'], FILTER_VALIDATE_IP))
            return $_SERVER['HTTP_X_FORWARDED_FOR'];
        else
            return $_SERVER['REMOTE_ADDR'];
    }
    // session hendler
    private function __session_start()
    {
        $start = true;
        if ( php_sapi_name() !== 'cli' ) {
            if ( version_compare(phpversion(), '5.4.0', '>=') )
                $start = (session_status() === PHP_SESSION_ACTIVE ? true : false);
            else 
                $start = (session_id() === '' ? false : true);
        } else $start = false;
        if ( $start === false ) session_start();
    }
    // user ID
    private function __userID()
    {
        if(isset($_SESSION['_ga_uid']) && !empty($_SESSION['_ga_uid']))
        {
            return $_SESSION['_ga_uid'];
        }
        else
        {
            $hash=mt_rand(1000000,9999999).'.'.time();
            $hash=str_replace(array("=","_","-","+"),"",base64_encode($hash));
            $_SESSION['_ga_uid']=$hash;
            return $hash;
        }
    }
}

// Activate SSGA
new cfSSGA(array(
    'gaID'=>'UA-xxxxxxx-2'
));

Feel free to test and use. Thanks!

Ivijan Stefan Stipić
  • 6,249
  • 6
  • 45
  • 78
  • 2
    Timing is not related to session duration (timing is the time it takes a user to do something - you send a hit type "timing" and the duration in milliseconds). Session duration is calculated as the time between the first and the last user interaction, so that's a completely different thing (and if you have only one interaction per user session duration should be 0). – Eike Pierstorff Apr 15 '15 at 09:11
  • Then, Why I have session duration 00:00:02 ? – Ivijan Stefan Stipić Apr 15 '15 at 09:13
  • Do I need to setup sc=start in my code? https://developers.google.com/analytics/devguides/collection/protocol/v1/parameters#sc – Ivijan Stefan Stipić Apr 15 '15 at 11:32
  • I am not interested in reading this code dump, but I did notice an antipattern. [Why check both isset() and !empty()](https://stackoverflow.com/a/4559976/2943403) – mickmackusa Sep 12 '22 at 23:12

0 Answers0