<?
/*
 * Todo: - admin menu to remove referer from table;
 *
 * History (admun): 
 *          0.90 initial version 
 *          0.91 Added the possibility to call pop,10 to show the most populair pages
 *               Minor bugfixes for htmlspecialchars
 *               Added substr to trim the line. Internet Explorer makes long lines instead of braking them
 *          0.92 Added timeoffset functionality to refWhen ...
 *          0.93 Added three display options (needs reinstallation!)
 *               Bugfixes and another calling option; lastall
 *               Added "-" on each refer
 *          0.94 use sql_table, add supportFeature
 *          0.95 add rel="nofollow"
 *          0.96 trim the line to other display mode
 *          0.97 add NP_BlackList support aka fight the referer spam!
 *               add code for plugin uninstall table remove (comment out by default)
 *          0.98 update to NP_BlackList 0.97+ support
 *
 * Start of Referer2 by pdreker: 04.03.2004
 * History: 0.10 initial version based on referer 0.93 by -=Xiffy=-
 *               Main Differences:
 *               - uses textarea for list options, because this is a lot more readable and has no length
 *                 restrictions. List are not comma separated any more, but newline separated (i.e. one
 *                 entry per line)
 *               - minor grammar and speling fixes. Clarified how the options have to be entered.
 *               - uses sql_table() instead of hardcoded table name.
 *               - IP banning supports CIDR notation (e.g. 192.168.1.0/24 to block all IPs in 192.168.1.0-255)
 *               - different defaults for <br /> insertion and display of referer time (exactly the other way
 *                 around).
 *               - added on option to automagically clean the referer DB table. This means, after you save the
 *                 options the domain bans will be applied to the database. This comes in handy, if a new
 *                 d*ckhead came along sprinkling p0rn links on your site: just add the domain to the ban
 *                 list, and if the option is checked the entries will be removed from the DB, so they don't
 *                 show up any more. WARNING: it is rather easy to shoot yourself in the foot, if you enter a
 *                 too wide ban (e.g. entering "x" as a ban will remove all referers with "x" in their domain
 *                 name... NO FURTHER QUESTIONS ASKED!
 *            0.11 small maintenance release
 *                 - changed the "lastall" target to look like all others (no table anymore). The old target 
 *                   was moved to "lastalltable"
 *            0.12 bugfix release (a.k.a. getting quick release)
 *                 - fixed a warning with empty blocklist or search engine list.
 *                 - fixed a typo in search engine handling which prevented search engines from being
 *                   recognized properly
 *            0.13 bugfix release (a.k.a. "Dont kill the referrer table")
 *                 - fixed a stupid oversight, which might delete all referrers from the DB table
 *                   if you had an empty entry there (yielded DELETE FROM .... WHERE ... LIKE "%%", which matches
 *                   every entry...)
 */
 
// to make this plugin works on Nucleus versions <=2.0 as well
if (!function_exists('sql_table'))
{
    function sql_table($name) { return 'nucleus_' . $name; }
}
 
class NP_Referer2 extends NucleusPlugin {
 
    function cidrCheck($ip_address, $cidr_address) {
        $first = substr($cidr_address, 0, strpos($cidr_address, "/"));
        $netmask = substr(strstr($cidr_address, "/"), 1);
 
        $first_bin = str_pad(decbin(ip2long($first)), 32, "0", STR_PAD_LEFT);
        $ip_bin = str_pad(decbin(ip2long($ip_address)), 32, "0", STR_PAD_LEFT);
        $netmask_bin = str_pad(str_repeat("1", (integer)$netmask), 32, "0", STR_PAD_RIGHT);
 
        // check: if (ip & mask) == first -> match
        // "compute" the "&"
        for($i = 0; $i<32; $i++) {
            if ($netmask_bin[$i] == "1") {
                $check_bin .= $ip_bin[$i];
            } else {
                $check_bin .= "0";
            }
        }
        $result = (strcmp($check_bin, $first_bin) == 0);
 
        return $result;
    }
 
    function supportsFeature($feature) {
        switch($feature) {
            case 'SqlTablePrefix':
                return 1;
            default:
                return 0;
        }
    }
 
    function getEventList() { return array('PostPluginOptionsUpdate'); }
 
    function event_PostPluginOptionsUpdate($data) {
        if ($data['context'] != 'global') return;
        if ($data['plugid'] != $this->GetID()) return;
 
        // if we get here we have just saved our own options
        $cleanDB = $this->getOption('cleanDB');
        if($cleanDB == 'yes') {
            $query = "DELETE FROM " . sql_table('plug_referer2') . " WHERE ";
            $filterlist    = explode("\n",$this->getOption(blockDomain));
            $gotone = false;
            foreach($filterlist as $block) {
                $block = rtrim($block);
                if($block != "") {
                    $query .= "ref_from LIKE '%$block%' OR ";
                    $gotone = true;
                }
            }
            // remove last "OR "
            $query = substr($query, 0, -4);
            // echo $query; // chicken ;-)
            if($gotone) mysql_query($query); // only do query if we really found something to clean
 
            // clear the option again
            if($this->getOption('autoResetCleanDB') == 'yes') {
                $this->setOption('cleanDB', 'no');
            }
        }
    }
 
    function doSkinVar($skintype, $what='last', $amount=10) {
        global $manager;
        global $blog;
        global $CONF;
        global $HTTP_REFERER;
        global $HTTP_HOST;
        $table_name = sql_table("plug_referer2");
        $logtime    = time();
        $refer      = $_SERVER['HTTP_REFERER']; //ED$ $HTTP_REFERER;
        $parsed     = parse_url($refer);
        $refParts   = explode("/", $refer);
        if ($_SERVER['QUERY_STRING']) {
            $pageRef    = $_SERVER['PHP_SELF']."_".$_SERVER['QUERY_STRING'];
        } else {
            $pageRef    = $_SERVER['PHP_SELF'];
        }
 
        // see if we need to block this referer
        if ($parsed[scheme] != "http")    { $refer = ""; }
        // not local please ...
        // ED$ if ($parsed[host] == $HTTP_HOST ) { $refer = ""; }
        if ($parsed[host] == $_SERVER['HTTP_HOST'] ) { $refer = ""; }
 
        $filterip      = explode("\n",$this->getOption(blockIp));
        $filterlist    = explode("\n",$this->getOption(blockDomain));        
        $searchengines = explode("\n",$this->getOption(searchengines));
        $addbreaks     = $this->getOption(addBR);
        $maxlength     = $this->getOption(maxlength);
        $showtime      = $this->getOption(showDateTime);
 
        // ignore filtered domains
        foreach($filterip as $block) {
            if(strstr($block, "/")) {
                // CIDR notation
                $block = rtrim($block);
                if($this->cidrCheck($_SERVER['REMOTE_ADDR'], $block)) {
                    $refer = "";
                }
            } else {
                // Single IP Address
                $block = rtrim($block);
                if ($block != "" && strstr($_SERVER['REMOTE_ADDR'], $block)) {
                    $refer = "";
                }
            }
        }
        foreach($filterlist as $block) {
            $block = rtrim($block);
            if ($block != "" && strstr($parsed[host],$block)) {
                $refer = "";
            }
        }
 
        // search engine ??
        foreach($searchengines as $engine ) {
            $engine = rtrim($engine);
            if ($engine != "" && strstr($parsed[host],$engine)) {
                $extra = $parsed[query]; // searchwords used ....
            }
        }
 
	// check for spam attempts, you never know !
	if ($refer != "" and $manager->pluginInstalled('NP_Blacklist') and $blacklist =& $manager->getPlugin('NP_Blacklist')) {
            if (floatval($blacklist->getVersion()) >= 0.96) {
                $spamcheck = array ('type'  => 'Referer', 'data'  => $refer, 'return'  => false);
                $manager->notify('SpamCheck', array ('spamcheck' => & $spamcheck));
            } else {
	        if (floatval($blacklist->getVersion()) == 0.95) {
		    $blacklist->blacklist('NP_Referer',$refer); 
		}
            }
        }
 
        // if we didn't block this, let's put it in the db ....
        // and if this is the first time we were called then ...
        if ($refer && !$this->count == 1) {
            if (! $extra) {
                // find the page title ...
                $fp = @fopen ($refer, "r");
                if ($fp){
                    $ref_str = fread($fp, 4096);
                    if (eregi("<title>(.*)</title>", $ref_str, $out)) {
                        $extra = htmlspecialchars ($out[1],ENT_QUOTES);
                    }
                }
                if (! $extra) {$extra = $parsed[host]." ".$parsed[path];}
            }
 
            // let's put it in the db now ...
            $query = "INSERT into $table_name (ref_to, ref_from, ref_extra)"
                   . " VALUES ('".$pageRef."','".$refer."','".$extra."')";
            mysql_query($query);
        }
        $this->count = 1; // we've been here now.
 
        // and put something on the page ....
        // build the appropiate query for $what
        if ($what == "lastall") {
            $query = "SELECT ref_from            AS refFrom"
                   . ",      ref_extra           AS refShow"
                   . ",      ref_to              AS refTo"
                   . ", UNIX_TIMESTAMP(ref_when) AS refWhen"
                   . " FROM $table_name "
                   . " ORDER BY ref_when DESC"
                   . " LIMIT ".$amount;
            $refs = mysql_query($query);
            if ($refs) {
                while ($ref = mysql_fetch_object($refs)) {
                    $ref->refShow = $this->searchString($ref->refFrom, $ref->refShow);
                    $temp = parse_url($ref->refFrom);
                    $host = $temp['host'];
                    $titletag = $host." : ".$ref->refShow;
                    if ($what == "item" ){
                        echo "- <a title=\"".$titletag."\" href=\"".htmlspecialchars($ref->refFrom)."\" rel=\"nofollow\">";
                        if ($showtime == yes) {
                            echo strftime("%e/%m/%g - %R",$ref->refWhen + ($blog->getTimeOffset() * 3600))." ";
                        }
                        echo stripslashes($ref->refShow)."</a>";
                    } else {
                        echo "- <a title=\"".$titletag."\" href=\"".htmlspecialchars($ref->refFrom)."\" rel=\"nofollow\">";
                        if ($showtime == yes) {
                            echo strftime("%R",$ref->refWhen + ($blog->getTimeOffset() * 3600))." ";
                        }
			if (strlen($ref->refShow) > $maxlength )
                        	echo substr(stripslashes($ref->refShow),0,$maxlength) . "...";
			else
                        	echo substr(stripslashes($ref->refShow),0,$maxlength);
 
 			echo "</a>";
                    }
                    if ($addbreaks == yes) {echo "<br />";}
                }
            }
        }
 
        if ($what == "lastalltable") {
            $query = "SELECT ref_from            AS refFrom"
                   . ",      ref_extra           AS refShow"
                   . ",      ref_to              AS refTo"
                   . ", UNIX_TIMESTAMP(ref_when) AS refWhen"
                   . " FROM $table_name "
                   . " ORDER BY ref_when DESC"
                   . " LIMIT ".$amount;
            $refs = mysql_query($query);
            if ($refs) {
                //echo "<table>";
                while ($ref = mysql_fetch_object($refs)) {
                    $ref->refTo = str_replace("_","?",$ref->refTo);
                    $ref->refShow = $this->searchString($ref->refFrom, $ref->refShow);
                    $temp = parse_url($ref->refFrom);
                    $host = $temp['host'];
                    $titletag = $host." : ".$ref->refShow;
                    //echo "<tr><td width=\"50%\">";
                    echo "- <a title=\"".$titletag."\" href=\"".htmlspecialchars($ref->refFrom)."\" rel=\"nofollow\">".strftime("%e/%m/%g - %R",$ref->refWhen + (0 * 3600))." ".stripslashes($ref->refShow)."</a>";
                    //echo "</td><td width=\"50%\">";
                    $linktxt  = substr($ref->refTo,strpos($ref->refTo,"?") + 1);
                    if( strpos($linktxt,"temid") > 0 ) {
                        $citemid = substr($linktxt,strpos($linktxt,"itemid=") + 7);
                        if ( strpos($citemid,"&") > 0) {
                            $citemid = substr($citemid,0, strpos($citemid,"&"));
                        }
                        $titleq = "SELECT ititle FROM ".sql_table('item')." WHERE inumber = ". $citemid;
                        $result = mysql_query($titleq);
                        $row = mysql_fetch_object($result);
                        if (! $row->ititle == "") {
                            $linktxt  = $row->ititle;
                        } else {
                            $linktxt = $citemid . "-" .$linktxt;
                        }
                    }
 
                    echo "<a href=\"".htmlspecialchars($ref->refTo)."\" rel=\"nofollow\"> -> ".$linktxt."</a>";
echo "</td></tr>";                    
                }
                echo "</table>";
            }
        }
        if ($what == "last" || $what  ==  "item") {
            $query = "SELECT ref_from            AS refFrom"
                   . ",      ref_extra           AS refShow"
                   . ", UNIX_TIMESTAMP(ref_when) AS refWhen"
                   . " FROM $table_name "
                   . " WHERE "
                   .  " ref_to = '".$pageRef."'"
                   . " ORDER BY ref_when DESC"
                   . " LIMIT ".$amount;
            $refs = mysql_query($query);
            if ($refs) {
                while ($ref = mysql_fetch_object($refs)) {
                    $ref->refShow = $this->searchString($ref->refFrom, $ref->refShow);
                    $temp = parse_url($ref->refFrom);
                    $host = $temp['host'];
                    $titletag = $host." : ".$ref->refShow;
                    if ($what == "item" ){
                        echo "- <a title=\"".$titletag."\" href=\"".htmlspecialchars($ref->refFrom)."\" rel=\"nofollow\">";
                        if ($showtime == yes) {
                            echo strftime("%e/%m/%g - %R",$ref->refWhen + ($blog->getTimeOffset() * 3600))." ";
                        }
                        echo stripslashes($ref->refShow)."</a>";
                    } else {
                        echo "- <a title=\"".$titletag."\" href=\"".htmlspecialchars($ref->refFrom)."\" rel=\"nofollow\">";
                        if ($showtime == yes) {
                            echo strftime("%R",$ref->refWhen + ($blog->getTimeOffset() * 3600))." ";
                        }
                        echo substr(stripslashes($ref->refShow),0,$maxlength)."</a>";
                    }
                    if ($addbreaks == yes) {echo "<br />";}
                }
            }
        }
        if ($what == "pop") { // which pages get hits from outside?
            $query = "SELECT ref_to    AS refTo"
                   . ",      ref_extra AS refShow"
                   . ", COUNT(ref_to)  AS refCount"
                   . " FROM $table_name "
                   . " GROUP BY ref_to "
                   . " ORDER BY refCount DESC"
                   . " LIMIT 0," .$amount; // skip the first that'll be the normal index ....
            $refs = mysql_query($query);
            if ($refs) {
                while ($ref = mysql_fetch_object($refs)) {
                    $ref->refTo = str_replace("_","?",$ref->refTo);
                    $titletag = $ref->refCount ." hits for: " .$ref->refTo;
                    $linktxt  = $ref->refCount." ".substr($ref->refTo,strpos($ref->refTo,"?") + 1);
                    if( strpos($linktxt,"itemid") > 0 ) {
                        $citemid = substr($linktxt,strpos($linktxt,"itemid=") + 7);
                        if ( strpos($citemid,"&") > 0) {
                            $citemid = substr($citemid,0, strpos($citemid,"&"));
                        }
                        $titleq = "SELECT ititle FROM ".sql_table('item')." WHERE inumber = ". $citemid;
                        $result = mysql_query($titleq);
                        $row = mysql_fetch_object($result);
                        if (! $row->ititle == "") {
                            $linktxt  = $ref->refCount." ".$row->ititle;
                        }
                    }
                    echo "- <a title=\"".$titletag."\" href=\"".htmlspecialchars($ref->refTo)."\" rel=\"nofollow\">".$linktxt."</a>";
                    if ($addbreaks == yes) {echo "<br />";}
                }
            }
        }
        if ($what == "top" || $what == "topall" ) { // get the top
            $query = "SELECT ref_from         AS refFrom"
                   . ",      ref_extra        AS refShow"
                   . ", UNIX_TIMESTAMP(ref_when) AS refWhen"
                   . ", COUNT(ref_from)       AS refCount"
                   . " FROM $table_name "
                   . " GROUP BY ref_from "
                   . " ORDER BY refCount DESC"
                   . " LIMIT " .$amount;
            $refs = mysql_query($query);
            if ($refs) {
                while ($ref = mysql_fetch_object($refs)) {
                    $ref->refShow = $this->searchString($ref->refFrom, $ref->refShow);
                    $temp = parse_url($ref->refFrom);
                    $host = $temp['host'];
                    $titletag = $host." : ".$ref->refShow;
                    echo  "- <a title=\"".$titletag."\" href=\"".htmlspecialchars($ref->refFrom)."\" rel=\"nofollow\">".$ref->refCount." ";
                    if ($what == "top") {
                        echo substr(stripslashes($ref->refShow),0,$maxlength);
                    } else {
			if (strlen($ref->refShow) > $maxlength )
                        	echo substr(stripslashes($ref->refShow),0,$maxlength) . "...";
			else
                        	echo substr(stripslashes($ref->refShow),0,$maxlength);
 
                        //echo substr(stripslashes($ref->refShow),0,$maxlength). "...;
                        //ED$ echo stripslashes($ref->refShow);
                    }
                    echo "</a>";
                    if ($addbreaks == yes) {echo "<br />";}
                }
            }
        }
    }
 
    function searchString($from, $query) {
        if (strstr($from,"google")    ||
            strstr($from,"ilse")      ||
            strstr($from,"altavista") ||
            strstr($from,"search.msn")) {
            parse_str($query,$res);
            $q = $res['q'];
            if (strstr($from,"google")) {
                $query = "[g] ";
            } else if (strstr($from,"ilse")) {
                $query = "[i] ";
                if ($q == "") {
                    $q = $res['search_for'];
                }
            } else if (strstr($from,"altavista")) {
                $query = "[a] ";
            } else if (strstr($from,"search.msn")) {
                $query = "[m] ";
            }
            $query .= htmlspecialchars($q);
        }
        if (strstr($from,"search.yahoo")) {
            parse_str($query,$res);
            $q = $res['p'];
            $query = "[y] " . htmlspecialchars($q);
        }
        return $query;
    }
 
    // name of plugin
    function getName()   { return 'Referer2';   }
    // author of plugin
    function getAuthor() { return 'pdreker, based on code by -=Xiffy=- inspired by: Mat Bennett, mod by admun (Edmond Hui)'; }
    function getURL()    { return 'http://www.dreker.org/'; }
    function getVersion(){ return '0.98'; }
    function getDescription() {
        return 'Keeps track of the referring pages. Call with <%Referer2(last,10)%> to show the last 10 referers.  <%Referer2(top,10)%> to see the top referer';
    }
 
    function install(){
        // create required table
        // NOT FINISHED WITH DEFAULTS !!
        $this->createOption('addBR','Add linebreaks <br /> to the links', 'yesno','no');
        $this->createOption('showDateTime', 'Show when the referring occured', 'yesno', 'yes');
        $this->createOption('autoResetCleanDB', 'Automatically reset "Clean referer table" option to "no"', 'yesno', 'yes');
        $this->createOption('maxlength','How many character to show at most', 'text', '30');
        $this->createOption('blockDomain','List of domains to ignore. Any domain containing this string is ' .
                            'ignored. One Entry per line','textarea',
                            "spankit\nbobbakazoo\nsearch4pornography\narizonasba\nchocoborancher\nchaiti");
        $this->createOption('blockIp','List of IP addresses to ignore. Any referral from on of these IPs is ' .
                            'ignored. You can use CIDR notation here (e.g. 192.168.1.0/24) ' .
                            'One Entry per line.','textarea',
                            "66.28.25.3\n64.75.32.137\n217.198.193.71\n18.85.23.46");
        $this->createOption('searchengines','List of search engine names. Any referral matching one of these ' .
                             'strings gets a special treatment (Lookup of search parameters). One Entry per Line. ' .
                             'The special treatment has to be coded into the plugin itself.','textarea',
                            "google\nsearch.yahoo\nilse\nfasttrack\nsearch.msn\nzoek\naltavista");
        $this->createOption('cleanDB', 'Clean the referer table after saving options?', 'yesno', 'no');
 
 
        $table_name = sql_table("plug_referer2");                    
        mysql_query ("CREATE TABLE $table_name
                    ( `ref_to` VARCHAR(60) NOT NULL,
                      `ref_when` TIMESTAMP NOT NULL,
                      `ref_from` VARCHAR(160) NOT NULL,
                      `ref_extra` VARCHAR(80),
                      KEY `from` (`ref_from`),
                      KEY `when` (`ref_when`),
                      KEY `to` (`ref_to`))");
    }
 
    function uninstall(){
        // uncomment below to delete created tables on uninstall
        //$table_name = sql_table("plug_referer2");                    
        //mysql_query ("DROP TABLE $table_name");
    }
 
    function getTableList() {
        return array(sql_table("plug_referer2"));
    }
}
?>
referer2code.txt · Last modified: 2006/07/05 13:03 (external edit)
 
Except where otherwise noted, content on this wiki is licensed under the following license: CC Attribution-Noncommercial-Share Alike 3.0 Unported
Recent changes RSS feed Donate Powered by PHP Valid XHTML 1.0 Valid CSS Driven by DokuWiki