Page 1 of 1

Statistics module Ignoring ip-addresses

Posted: Mon Aug 27, 2007 3:01 pm
by bterkuile
I looked into the statistics module and the Ignoring of ip-addresses. The first thing I noticed is that when a visitor should be ignored, the pagecount is increased. This can be prevented by putting the increase inside the IgnoreVisitor test. The Execute function will look like:

Code: Select all

function Execute($showwhat) {
    $this->ReadSettings();
    if (!$this->IgnoreVisitor()) {
		$this->IncreaseValue("count_total_pageviews");
		$this->Log("*** STARTING SESSION ***");
		  if (!$this->ExistingVisitor()) {
	 		  $this->CleanVisitors(); //needed every time? Yes... too slow if done too seldom
			  $this->DoComplete();
		  } else {
  			$this->DoUpdate();
	  	}
		$this->Log("*** ENDING SESSION ***");
		$this->Log("");
    }   
 	return $this->GetResult($showwhat);
}
The other thing is that I like the Statistics module to be able to handle wild cards and ranges. So the next statement would be possible:

Code: Select all

10;192.168;12.34/56.*.55
here number/number is a range and * matches anything (equivalent with 0/255)
Since I did not found a good formula for that on the net, I wrote one myself. I think the performance should be quite good. The first change is the IgnoreVisitor function. This should be:

Code: Select all

function IgnoreVisitor() {
		// ip addresses to ignore are separated by semicolons (like 172.10.1.93;172.10.1.94)
		$ip = $_SERVER["REMOTE_ADDR"];
		if (isset($ip)) {
			$ignoreips=trim($this->ignoreips,' ;');
			if($ignoreips=='')return false;
			$aIp=explode('.',$ip);
			foreach(explode(';',$ignoreips)as $ignoreip){
				$ignoreip=trim($ignoreip,'. ');
				$aIg = explode('.',$ignoreip);
				for($i=0;$i<count($aIg);$i++){
					$result = $this->IgnoreSubIp($aIp[$i],$aIg[$i]);
					if(!$result)break;// we are sure not to ignore;
				}
				if($i==count($aIg)){
					$this->Log("Ignoring visitor because of ignore IP-list");
					return true; // This is a ban, don't look further
				}
			}
		}
		return false; // no match has occured
}
And I added a new function:

Code: Select all

function IgnoreSubIp($ip,$ban){
		/** return false if sure not blocking **/
		if($ban=='*')return true;
		if(is_numeric($ban)&&$ban!=$ip)return false;
		if(preg_match('/(\d{1,3})\/(\d{1,3})/',$ban,$matches)){
			if($ip<$matches[1]||$ip>$matches[2])return false;
		}
		// Error invalid ban description
		return true;
}
for the record: I tested in Statistics version 0.8.0b1

Good luck with this one!

ps, something tells me that is should be possible in one or two regexps, if you know them please let me know!