hour = date("G"); $this->day = date("j"); $this->month = date("n"); $this->year = date("Y"); # Get the ip of the client browser. if (getenv("HTTP_X_FORWARDED_FOR")) { # Client uses a proxy server. $client_ip = getenv("HTTP_X_FORWARDED_FOR"); $this->ip = substr($client_ip, 0, strpos($client_ip, ',')); if ($this->ip == "") $this->ip = getenv("HTTP_CLIENT_IP"); } else { # Client does not use proxy. $this->ip = getenv("REMOTE_ADDR"); } # Check the php version. if ($this->_checkMinimumVersion("4.1.0")) { # php version is at least 4.1.0 $this->webpage = $_SERVER["PHP_SELF"]; $this->user_agent = $_SERVER["HTTP_USER_AGENT"]; if (isset($_COOKIE["PHPSESSID"])) $this->sessionID = $_COOKIE["PHPSESSID"]; } else { # php version is older than 4.1.0 global $HTTP_SERVER_VARS; global $HTTP_COOKIE_VARS; $this->webpage = $HTTP_SERVER_VARS["PHP_SELF"]; $this->user_agent = $HTTP_SERVER_VARS["HTTP_USER_AGENT"]; if (isset($HTTP_COOKIE_VARS["PHPSESSID"])) $this->sessionID = $HTTP_COOKIE_VARS["PHPSESSID"]; } # Get the relative path of the webpage from the document root. if (sizeof($subdirs = explode("/", $url_root)) > 0) { $webpath = explode("/", $this->webpage); $this->webpage = ""; for ($i = sizeof($webpath) - 1; $i >= sizeof($subdirs); $i--) $this->webpage = "/" . $webpath[$i] . $this->webpage; } if ($data_path === null) { $data_path = $file_path . '/data'; } $this->data_dir = $data_path; # Set the path to the data files. $this->log_data["track"] = $this->data_dir . "track_" . $this->month . "_" . $this->year . ".log"; $this->log_data["hits"] = $this->data_dir . "hits.log"; $this->spider_library = $this->data_dir . "spider.lib"; # Place the pointer at the last user track. $this->currentIndex = sizeof(file($this->log_data["track"])) - 1; if ($this->currentIndex < 0) $this->currentIndex = 0; } /* ** Function: _log ** Input: VOID ** Output: VOID ** Description: Log the page impressions and visits. */ public function _log($category) { switch ($category) { case "impression": $subject = $this->webpage; break; case "visit": $subject = $category; break; } # This Function checks whether there is already an entry for the webpage # in the hits_data. If there is one, it will increment the number # of page impressions. If there is none, it will initialize the number of # page impressions of that webpage with 1. Same procedure for logging the # visits, except that the start value can be modified if prefered. $log_file = file($this->log_data["hits"]); if ($this->_incrementIfEqual($subject, $log_file, 0, 1) != 1) { # There is no entry yet, so we have to add a new one. if (!strcmp($subject, "visit")) $start_value = $this->visitorStartValue; else $start_value = 1; $line = $subject . "|" . $start_value . "|\r\n"; $this->_writeLine($this->log_data["hits"], $line, "a"); } else { # Write the already changed array back to the hits_data. $this->_writeArray($this->log_data["hits"], $log_file, "w"); } } /* ** Function: _getNumberOf ** Input: VOID ** Output: INTEGER ** Description: Get the number of page impressions of actual webpage or ** the number of visitors of the website. */ public function _getNumberOf($category) { switch ($category) { case "impression": $subject = $this->webpage; break; case "visit": $subject = "visit"; break; } $log_file = file($this->log_data["hits"]); for ($i = 0; $i < sizeof($log_file); $i++) { $log_line = explode("|", $log_file[$i]); if (!strcmp($log_line[0], $subject)) { return $log_line[1]; break; } } } /* ** Function: _processPageRequest ** Input: BOOLEAN cookie_support ** Output: VOID ** Description: Does all necessary work to count visitors, page impressions and stores the user track. */ public function _processPageRequest($cookie_support) { if (!$this->_identifyClientAs("spider")) { # Start the main process. switch ($cookie_support) { case TRUE: # User was already counted, cookies are supported. if ($this->_compare("sessionID") || $this->_compare("ip")) { # Add the actual webpage to the user track and # increase the page impressions. $this->_trackVisitor("old visitor"); $this->_log("impression"); } else { # We have to search the corresponding user # track of the actual user in the logfile. # If the index is < 0, we have reached the # end of the logfile. We log the new visitor, # which has never visited us before. $this->currentIndex--; if ($this->currentIndex >= 0) $this->_processPageRequest(TRUE); else { $this->_log("visit"); $this->_trackVisitor("new visitor"); $this->_log("impression"); } } break; case FALSE: # No session id generated yet. Either this is # the first page request of the visitor or the # client browser does not support cookies. if ($this->_compare("ip")) { # Client browser does not support cookies but # we can track the visitor by the IP. $this->_trackVisitor("old visitor"); $this->_log("impression"); } else if ($this->_reloadRestriction()) { # Another visitor has requested the website during # the period of time defined as reload restriction. # It is possible that the visitor we are actually # tracking has already been counted during that reload # restriction. To check this, we search the IP in the # older user tracks until the elapsed time is higher # than the reload restriction. # If the index is < 0, we have reached the # end of the logfile. We log the new visitor, # which has never visited us before. $this->currentIndex--; if ($this->currentIndex >= 0) $this->_processPageRequest(FALSE); else { $this->_log("visit"); $this->_trackVisitor("new visitor"); $this->_log("impression"); } } else { # A new visitor has entered the website. $this->_log("visit"); $this->_trackVisitor("new visitor"); $this->_log("impression"); } break; } } } /* ** Function: _trackVisitor ** Input: STRING mode ** Output: VOID ** Description: Track the user through the website. */ public function _trackVisitor($mode) { $log_file = file($this->log_data["track"]); switch ($mode) { case "new visitor": # Start a new user track. $user_track = "|" . $this->ip . "|" . time() . "|" . time() . "|" . $this->webpage . "|\r\n"; # Add the new user track to the logfile. $this->_writeLine($this->log_data["track"], $user_track, "a"); break; case "old visitor": # Add the actual webpage to the existing user track. # Try to add the session id to the user track. $user_track = explode("|", $log_file[$this->currentIndex]); if (isset($this->sessionID)) $user_track[0] = $this->sessionID; # Track the time of the actual request. $user_track[3] = time(); $user_track[sizeof($user_track) - 1] = $this->webpage . "|\r\n"; $log_file[$this->currentIndex] = implode("|", $user_track); # Write the changed user track back to the logfile. $this->_writeArray($this->log_data["track"], $log_file, "w"); break; } } /* ** Function: _compare ** Input: STRING subject ** Output: BOOLEAN ** Description: Returns TRUE if two compared subjects are equal. */ public function _compare($subject) { $log_file = file($this->log_data["track"]); $user_track = explode("|", $log_file[$this->currentIndex]); switch ($subject) { case "ip": # Compare the object ip with the ip # of the user track. if (isset($user_track[1]) && !strcmp($user_track[1], $this->ip)) return TRUE; else return FALSE; break; case "sessionID": # Compare the object session id with the # session id stored in the user track. if (isset($this->sessionID) && !strcmp($user_track[0], $this->sessionID)) return TRUE; else return FALSE; break; } } /* ** Function: _reloadRestriction ** Input: VOID ** Output: BOOLEAN ** Description: Returns TRUE if the time elapsed between the previous page request and the actual page request is smaller than the period of time defined as reloadRestriction. */ public function _reloadRestriction() { $log_file = file($this->log_data["track"]); $user_track = explode("|", $log_file[$this->currentIndex]); if (isset($user_track[3]) && (time() - $user_track[3] < $this->reloadRestriction)) return TRUE; else return FALSE; } /* ** Function: _identifyClientAs ** Input: VOID ** Output: STRING spiderline[1] or FALSE ** Description: Check if the current visitor is a member of a category. */ public function _identifyClientAs($category) { switch ($category) { case "spider": $library_data = $this->spider_library; $subject = $this->user_agent; break; } $library_file = file($library_data); # Compare the spider library with the user_agent. # If there are any matches, the current page has # been requested by a spider or a robot. for ($i = 0; $i < sizeof($library_file); $i++) { $library_line = explode("|", $library_file[$i]); if (preg_match('/'.$library_line[0].'/i', $subject)) return $library_line[1]; } return FALSE; } } ?>