Link to home
Start Free TrialLog in
Avatar of egoselfaxis
egoselfaxis

asked on

Need help fixing PHP class that tracks a visitor's session duration on website

I'm trying to implement the following PHP based class on a client's website:

http://www.phpclasses.org/package/1681-PHP-Keep-track-of-the-time-users-spend-in-a-site.html

(You can download the attached zip file to view the source code & examples .. or just scroll down)

The class is supposed to keep track of how much time a visitor spends on website (even as they navigate to different pages or websites).  From what I can tell, it appears to be doing all of this by writing cookies and javascript, and then doing some arithmetic using the retrieved cookie values.

The class is rather buggy, however.  By that I mean that sometimes the script works .. and other times it doesn't, .. and I can't figure out why.  

Here's the PHP source code for the class file:

<?php

class time_online {

   function time_online() {

      $this -> userID  = $_COOKIE["time_online_ID"]; // user's ID
      $this -> userTT  = $_COOKIE["time_online_TT"]; // user's total time on site
      $this -> userST  = $_COOKIE["time_online_ST"]; // time when user entered the site
      $this -> userTO  = $_COOKIE["time_online_TO"]; // time that the user has been online this sesion
      $this -> displayID = 0; // ID used to generate diferent script in case of multiple call of display() function

      if ($this -> userID != "") {

         if ($this -> userST == "") {

            $this -> userST = time();
            setcookie("time_online_ST", $this -> userST);
         }

         $this -> userLPT = time() - $this -> userST - $this -> userTO;

         $this -> userTT += $this -> userLPT;
         setcookie("time_online_TT", $this -> userTT, time()+60*60*60*60*60);

         $this -> userTO = time() - $this -> userST;
         setcookie("time_online_TO", $this -> userTO);

         $this -> userTO = time_online::normalizare($this -> userTO);
         $this -> userTT = time_online::normalizare($this -> userTT);
      }

      if ($this -> userID == "") {

         time_online::newID();
      }

   }

   function newID() {

         $this -> userID = md5(rand());
         $this -> userST = time();
         $this -> userTO = 0;
         $this -> userTT = 0;
         setcookie("time_online_ID", $this -> userID, time()+(60*60*24*365*10));
         setcookie("time_online_ST", $this -> userST);
         setcookie("time_online_TO", $this -> userTO);
         setcookie("time_online_TT", $this -> userTT, time()+(60*60*24*365*10));
   }

   function normalizare($secunde) {

	     $minute  = $secunde / 60;
	     $secunde = $secunde % 60;
	     $ore     = $minute  / 60;
	     $minute  = $minute  % 60;
		 $zile    = $ore     / 24;
	     $ore     = $ore     % 24;

	     return $timp = array("days" => (int)$zile, "hours" => $ore, "minutes" => $minute, "seconds" => $secunde);
   }

   function display_time($type){

      $this -> displayID++;

      if ($type == "current_page") {

         $time_start_multiply = 0;
      }

      if ($type == "current_session") {

         $time_start_multiply = $this -> userTO["days"]*24*60*60 + $this -> userTO["hours"]*60*60 + $this -> userTO["minutes"]*60 + $this -> userTO["seconds"];
      }

      if ($type == "total_time") {

         $time_start_multiply = $this -> userTT["days"]*24*60*60 + $this -> userTT["hours"]*60*60 + $this -> userTT["minutes"]*60 + $this -> userTT["seconds"];
      }

      echo "
	           <script type=\"text/javascript\">
	           document.writeln(\"<span id=\\\"time_online" . $this -> displayID . "\\\"></span>\");

	           zi_inceput" . $this -> displayID . " = new Date();
	           ceas_start" . $this -> displayID . " = zi_inceput" . $this -> displayID . ".getTime();

	           function initStopwatch" . $this -> displayID . "() {

               var timp_pe_pag" . $this -> displayID . " = new Date();
   	           return((timp_pe_pag" . $this -> displayID . ".getTime()+(1000*$time_start_multiply) - ceas_start" . $this -> displayID . ")/1000);
	           }
	           function getSecs" . $this -> displayID . "() {


            	  var tSecs" . $this -> displayID . " = Math.round(initStopwatch" . $this -> displayID . "());
	              var iSecs" . $this -> displayID . " = tSecs" . $this -> displayID . " % 60;
	              var iMins" . $this -> displayID . " = Math.round((tSecs" . $this -> displayID . "-30)/60);
	              var iHour" . $this -> displayID . " = Math.round((iMins" . $this -> displayID . "-30)/60);
	              var iMins" . $this -> displayID . " = iMins" . $this -> displayID . " % 60;
	              var iDays" . $this -> displayID . " = Math.round((iHour" . $this -> displayID . "-11)/24);
               if (iDays" . $this -> displayID . " == -0) {iDays" . $this -> displayID . " *= (-1)}; // Stupid Opera :)
	              var iHour" . $this -> displayID . " = iHour" . $this -> displayID . " % 24;
	              var sSecs" . $this -> displayID . " = \"\" + ((iSecs" . $this -> displayID . " > 9) ? iSecs" . $this -> displayID . " : \"0\" + iSecs" . $this -> displayID . ");
	              var sMins" . $this -> displayID . " = \"\" + ((iMins" . $this -> displayID . " > 9) ? iMins" . $this -> displayID . " : \"0\" + iMins" . $this -> displayID . ");
	              var sHour" . $this -> displayID . " = \"\" + ((iHour" . $this -> displayID . " > 9) ? iHour" . $this -> displayID . " : \"0\" + iHour" . $this -> displayID . ");

               document.getElementById('time_online" . $this -> displayID . "').innerHTML=iDays" . $this -> displayID . "+\":\"+sHour" . $this -> displayID . "+\":\"+sMins" . $this -> displayID . "+\":\"+sSecs" . $this -> displayID . ";
               window.setTimeout('getSecs" . $this -> displayID . "()',1000);

	           }
               window.setTimeout('getSecs" . $this -> displayID . "()',1000)

	           </script>
      ";


   }
}

?>

Open in new window


.. and here's an example of how to implement it on a website:

<?php
	include ("time_online.class.php");
	$test = new time_online;
	echo "<br> Curent time on site: ";
	$test -> display_time("current_session");
?>

Open in new window


Can anyone here help me troubleshoot or fix this code?  Why does it not work consistently?  And can it even be fixed?

By the way -- I'm entirely open to the idea of scrapping this script completely in favor or implementing a better / more reliable approach.  

Thanks!
- Yvan
time-online-2007-01-06.zip
ASKER CERTIFIED SOLUTION
Avatar of Ray Paseur
Ray Paseur
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of egoselfaxis
egoselfaxis

ASKER

Hi Ray.  I actually did a bit more tinkering with the script after I posted my question, and think I may have figured out what the problem was.  There were some comments in the class file that I believe were being interpreted as content and interfering with the headers. So I simply removed those comments, and then updated each page of the site so that it starts with the following (instead of instantiating the class at the end of each page):

<?php include ("time_online.class.php");$timer = new time_online; ?>

That seemed to do the trick! I tried it about 10 times in a row (after deleting all domain and session cookies and then clearing my browser's cache) .. and it worked every time.  

I'm a big fan of Google Analytics too -- but it wouldn't have worked for me in this case, since I needed to be able to trigger an event at a specific time (ie: reveal a "contact us now" form after the new visitor has been on the site for at least 5 minutes).  

Anyways -- I still appreciate your help.  

Cheers,
- Yvan
Why wait five minutes?  How about 10 seconds?  You might consider a jQuery modal window or something like that.  Just a thought.

Thanks for the points, ~Ray