From 75a4d9b3d48d4c1bd327868c87cefa4ca36d64de Mon Sep 17 00:00:00 2001 From: marko Date: Wed, 9 Jan 2019 13:13:35 +0100 Subject: [PATCH] =?UTF-8?q?Zumindest=20vorr=C3=BCbergehend=20den=20UserAge?= =?UTF-8?q?nt=20mitloggen.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Erweiterung des hitcounters um den UserAgentString modified: markdownExperiment/admin/phpcount/phpcountLog.php new file: markdownExperiment/src/phpLibs/phpCount/phpcount.php - Es ist inzwischen schon weit genug vom ursprünglichen entfernt, das Repository wird nicht mehr weiterentwickelt, also brauchen wir es auch nicht mehr deleted: markdownExperiment/phpLib/phpcount --- .../admin/phpcount/phpcountLog.php | 15 +- .../markdownExperiment/phpLib/phpcount | 1 - .../src/phpLibs/phpCount/phpcount.php | 353 ++++++++++++++++++ 3 files changed, 358 insertions(+), 11 deletions(-) delete mode 160000 homepage/redesign2018/markdownExperiment/phpLib/phpcount create mode 100644 homepage/redesign2018/markdownExperiment/src/phpLibs/phpCount/phpcount.php diff --git a/homepage/redesign2018/markdownExperiment/admin/phpcount/phpcountLog.php b/homepage/redesign2018/markdownExperiment/admin/phpcount/phpcountLog.php index 09e8820..e24cce6 100644 --- a/homepage/redesign2018/markdownExperiment/admin/phpcount/phpcountLog.php +++ b/homepage/redesign2018/markdownExperiment/admin/phpcount/phpcountLog.php @@ -18,13 +18,7 @@ try{ ); $dailyHitsQuery->execute(); $dailyHitsList = $dailyHitsQuery->fetchAll(PDO::FETCH_ASSOC); -/* - $uniqueHitsQuery = $dbConnection->prepare( - "SELECT pageid, hitcount FROM `phpcount_hits` WHERE isunique=1 ORDER BY hitcount DESC" - ); - $uniqueHitsQuery->execute(); - $uniqueHitsList = $uniqueHitsQuery->fetchAll(PDO::FETCH_ASSOC); -*/ + $whereClauses=array(); if($_GET['userHash']) $whereClauses[]="userHash='".$_GET['userHash']."'"; @@ -36,7 +30,7 @@ try{ $whereClause = join(" AND ", $whereClauses); $pagehitsQuery = $dbConnection->prepare( - "SELECT DATE(timeStamp) as date, TIME(timestamp) as time, pageId, userHash FROM `phpcount_pageHits` ". + "SELECT DATE(timeStamp) as date, TIME(timestamp) as time, pageId, userHash, userAgentString FROM `phpcount_pageHits` ". ($whereClause?"WHERE ".$whereClause." ":""). "ORDER BY timeStamp DESC;" ); @@ -70,13 +64,14 @@ catch(PDOException $db_error){
- + ". "". "". "". - "" ); + ""; ?>
datetimepageIduserHash
datetimepageIduserHashuserAgentString
".$pagehitsEntry['date']."".$pagehitsEntry['time']."".urldecode($pagehitsEntry['pageId'])."".substr($pagehitsEntry['userHash'], 0, 5)."...
".substr($pagehitsEntry['userHash'], 0, 5)."..." ). + "".$pagehitsEntry['userAgentString']."
diff --git a/homepage/redesign2018/markdownExperiment/phpLib/phpcount b/homepage/redesign2018/markdownExperiment/phpLib/phpcount deleted file mode 160000 index f1d3b54..0000000 --- a/homepage/redesign2018/markdownExperiment/phpLib/phpcount +++ /dev/null @@ -1 +0,0 @@ -Subproject commit f1d3b543d2175a81e95d1233c249cbaba6fd34d4 diff --git a/homepage/redesign2018/markdownExperiment/src/phpLibs/phpCount/phpcount.php b/homepage/redesign2018/markdownExperiment/src/phpLibs/phpCount/phpcount.php new file mode 100644 index 0000000..fbd46b3 --- /dev/null +++ b/homepage/redesign2018/markdownExperiment/src/phpLibs/phpCount/phpcount.php @@ -0,0 +1,353 @@ +. +*/ + +/* + * This PHP Class provides a hit counter that is able to track unique hits + * without recording the visitor's IP address in the database. It does so by + * recording the hash of the IP address and page name. + * + * By hashing the IP address with page name as salt, you prevent yourself from + * being able to track a user as they navigate your site. You also prevent + * yourself from being able to recover anyone's IP address without brute forcing + * through all of the assigned IP address blocks in use by the internet. + * + * Contact: havoc AT defuse.ca + * WWW: https://defuse.ca/ + * + * USAGE: + * In your script, use reqire_once() to import this script, then call the + * functions like PHPCount::AddHit(...); See each function for help. + * + * NOTE: You must set the database credentials in the InitDB method. + */ + +//global $phpcountConfig; +//var_dump($phpcountConfig); + + +class PHPCount +{ + /* + * Defines how many seconds a hit should be rememberd for. This prevents the + * database from perpetually increasing in size. Thirty days (the default) + * works well. If someone visits a page and comes back in a month, it will be + * counted as another unique hit. + */ + const HIT_OLD_AFTER_SECONDS = 2592000; // default: 30 days. + + // Don't count hits from search robots and crawlers. + const IGNORE_SEARCH_BOTS = true; + + // Don't count the hit if the browser sends the DNT: 1 header. + const HONOR_DO_NOT_TRACK = false; + + private static $IP_IGNORE_LIST = array( + '127.0.0.1', + ); + + private static $DB = false; + + private static function InitDB() + { + global $phpcountConfig; + //var_dump($phpcountConfig); + + if(self::$DB) + return; + + try + { + // TODO: Set the database login credentials. + //echo(""); + } + catch(Exception $e) + { + self::$DB = false; + echo("Failed to connect to phpcount database (".$e->getMessage().")\n"); +// die('Failed to connect to phpcount database ('.$e->getMessage().')'); + } + } + + public static function setDBAdapter($db) + { + self::$DB = $db; + return $db; + } + + /* + * Adds a hit to a page specified by a unique $pageID string. + */ + public static function AddHit($pageID) + { + if(self::IGNORE_SEARCH_BOTS && self::IsSearchBot()) + return false; + if(in_array($_SERVER['REMOTE_ADDR'], self::$IP_IGNORE_LIST)) + return false; + if( + self::HONOR_DO_NOT_TRACK && + isset($_SERVER['HTTP_DNT']) && $_SERVER['HTTP_DNT'] == "1" + ) { + return false; + } + + self::InitDB(); + + self::Cleanup(); + if(self::UniqueHit($pageID)) + { + self::CountHit($pageID, true); + self::LogHit($pageID); + } + self::CountHit($pageID, false); + + self::LogPageHit($pageID); + + return true; + } + + /* + * Returns (int) the amount of hits a page has + * $pageID - the page identifier + * $unique - true if you want unique hit count + */ + public static function GetHits($pageID, $unique = false){ + global $phpcountConfig; + self::InitDB(); + + try{ + $q = self::$DB->prepare( + 'SELECT hitcount FROM '.$phpcountConfig["db"]["hitsTable"].' + WHERE pageid = :pageid AND isunique = :isunique' + ); + $q->bindParam(':pageid', $pageID); + $q->bindParam(':isunique', $unique); + $q->execute(); + } + catch(Exeption $e){ + echo("Failed to getHits from phpcount database (".$e->getMessage().")\n"); + return -1; + } + + if(($res = $q->fetch()) !== FALSE) + { + return (int)$res['hitcount']; + } + else + { + //die("Missing hit count from database!"); + return 0; + } + } + + /* + * Returns the total amount of hits to the entire website + * When $unique is FALSE, it returns the sum of all non-unique hit counts + * for every page. When $unique is TRUE, it returns the sum of all unique + * hit counts for every page, so the value that's returned IS NOT the + * amount of site-wide unique hits, it is the sum of each page's unique + * hit count. + */ + public static function GetTotalHits($unique = false){ + global $phpcountConfig; + + self::InitDB(); + + $q = self::$DB->prepare( + 'SELECT hitcount FROM '.$phpcountConfig["db"]["hitsTable"].' WHERE isunique = :isunique' + ); + $q->bindParam(':isunique', $unique); + $q->execute(); + $rows = $q->fetchAll(); + + $total = 0; + foreach($rows as $row) + { + $total += (int)$row['hitcount']; + } + return $total; + } + + /*====================== PRIVATE METHODS =============================*/ + + private static function IsSearchBot() + { + // Of course, this is not perfect, but it at least catches the major + // search engines that index most often. + $keywords = array( + 'bot', + 'spider', + 'spyder', + 'crawlwer', + 'walker', + 'search', + 'yahoo', + 'holmes', + 'htdig', + 'archive', + 'tineye', + 'yacy', + 'yeti', + ); + + $agent = strtolower($_SERVER['HTTP_USER_AGENT']); + + foreach($keywords as $keyword) + { + if(strpos($agent, $keyword) !== false) + return true; + } + + return false; + } + + private static function UniqueHit($pageID){ + global $phpcountConfig; + + $ids_hash = self::IDHash($pageID); + + $q = self::$DB->prepare( + 'SELECT `time` FROM '.$phpcountConfig["db"]["nodupesTable"].' WHERE ids_hash = :ids_hash' + ); + $q->bindParam(':ids_hash', $ids_hash); + $q->execute(); + + if(($res = $q->fetch()) !== false) + { + if($res['time'] > time() - self::HIT_OLD_AFTER_SECONDS) + return false; + else + return true; + } + else + { + return true; + } + } + + private static function LogHit($pageID){ + global $phpcountConfig; + + $ids_hash = self::IDHash($pageID); + + $q = self::$DB->prepare( + 'SELECT `time` FROM '.$phpcountConfig["db"]["nodupesTable"].' WHERE ids_hash = :ids_hash' + ); + $q->bindParam(':ids_hash', $ids_hash); + $q->execute(); + + $curTime = time(); + + if(($res = $q->fetch()) !== false) + { + $s = self::$DB->prepare( + 'UPDATE '.$phpcountConfig["db"]["nodupesTable"].' SET `time` = :time WHERE ids_hash = :ids_hash' + ); + $s->bindParam(':time', $curTime); + $s->bindParam(':ids_hash', $ids_hash); + $s->execute(); + } + else + { + $s = self::$DB->prepare( + 'INSERT INTO '.$phpcountConfig["db"]["nodupesTable"].' (ids_hash, `time`) + VALUES( :ids_hash, :time )' + ); + $s->bindParam(':time', $curTime); + $s->bindParam(':ids_hash', $ids_hash); + $s->execute(); + } + } + + private static function LogPageHit($pageId){ + global $phpcountConfig; + + try{ + $q = self::$DB->prepare( + 'INSERT INTO '.$phpcountConfig["db"]["pagehitsTable"].' (userHash, pageId, userAgentString) VALUES (:idsHash, :pageId, :userAgentString);' + ); + $q->bindParam(':idsHash', self::userHash()); + $q->bindParam(':pageId', $pageId); + $q->bindParam(':userAgentString', $_SERVER['HTTP_USER_AGENT']); + $q->execute(); + } + catch(Exeption $e){ + echo("Failed to logPageHits to phpcount database (".$e->getMessage().")\n"); + return -1; + } + return 0; + } + + private static function CountHit($pageID, $unique){ + global $phpcountConfig; + + //echo("DEBUG: Counting Hit on ".$pageID."\n"); + try{ + $q = self::$DB->prepare( + "INSERT INTO ".$phpcountConfig["db"]["hitsTable"]." (pageid, isunique, hitcount) VALUES (:pageid, :isunique, 1) " . + "ON DUPLICATE KEY UPDATE hitcount = hitcount + 1" + ); + $q->bindParam(':pageid', $pageID); + $unique = $unique ? '1' : '0'; + $q->bindParam(':isunique', $unique); + $q->execute(); + } + catch(Exception $e){ + die('phpcount failed to CountHit ('.$e->getMessage().')'); + } + + } + + private static function IDHash($pageID) + { + $visitorID = $_SERVER['REMOTE_ADDR'] . $_SERVER['HTTP_USER_AGENT']; + return hash("SHA256", $pageID . $visitorID); + } + + private static function userHash() + { + $visitorID = $_SERVER['REMOTE_ADDR'] . $_SERVER['HTTP_USER_AGENT']; + return hash("SHA256", $visitorID); + } + + private static function Cleanup(){ + global $phpcountConfig; + + $last_interval = time() - self::HIT_OLD_AFTER_SECONDS; + + $q = self::$DB->prepare( + 'DELETE FROM '.$phpcountConfig["db"]["nodupesTable"].' WHERE `time` < :time' + ); + $q->bindParam(':time', $last_interval); + $q->execute(); + + $q = self::$DB->prepare( + 'DELETE FROM '.$phpcountConfig["db"]["pageHitsTable"].' WHERE `timeStamp` < :time' + ); + $q->bindParam(':time', $last_interval); + $q->execute(); + } +}