add('name', PLUGIN_EVENT_STATISTICS_NAME); $propbag->add('description', PLUGIN_EVENT_STATISTICS_DESC); $propbag->add('stackable', false); $propbag->add('author', 'Arnan de Gans, Garvin Hicking, Fredrik Sandberg, kalkin'); $propbag->add('version', '1.50'); $propbag->add('requirements', array( 'serendipity' => '0.8', 'smarty' => '2.6.7', 'php' => '4.1.0' )); $propbag->add('groups', array('STATISTICS')); $propbag->add('event_hooks', array( 'backend_sidebar_entries' => true, 'backend_sidebar_entries_event_display_statistics' => true, 'frontend_configure' => true )); $propbag->add('configuration', array('max_items','ext_vis_stat','stat_all','banned_bots')); } function introspect_config_item($name, &$propbag) { switch($name) { case 'max_items': $propbag->add('type', 'string'); $propbag->add('name', PLUGIN_EVENT_STATISTICS_MAX_ITEMS); $propbag->add('description', PLUGIN_EVENT_STATISTICS_MAX_ITEMS_DESC); $propbag->add('default', 20); break; case 'ext_vis_stat': $select = array('no' => PLUGIN_EVENT_STATISTICS_EXT_OPT1, 'yesBot' => PLUGIN_EVENT_STATISTICS_EXT_OPT2, 'yesTop' => PLUGIN_EVENT_STATISTICS_EXT_OPT3); $propbag->add('type', 'select'); $propbag->add('name', PLUGIN_EVENT_STATISTICS_EXT_ADD); $propbag->add('description', PLUGIN_EVENT_STATISTICS_EXT_ADD_DESC); $propbag->add('select_values', $select); $propbag->add('default', 'no'); break; case 'stat_all': $select = array('no' => PLUGIN_EVENT_STATISTICS_EXT_ALL1, 'yes' => PLUGIN_EVENT_STATISTICS_EXT_ALL2); $propbag->add('type', 'select'); $propbag->add('name', PLUGIN_EVENT_STATISTICS_EXT_ALL); $propbag->add('description', PLUGIN_EVENT_STATISTICS_EXT_ALL_DESC); $propbag->add('select_values', $select); $propbag->add('default', 'yes'); break; case 'banned_bots': $select = array('yes' => PLUGIN_EVENT_STATISTICS_BANNED_HOSTS1, 'no' => PLUGIN_EVENT_STATISTICS_BANNED_HOSTS2); $propbag->add('type', 'select'); $propbag->add('name', PLUGIN_EVENT_STATISTICS_BANNED_HOSTS); $propbag->add('description', PLUGIN_EVENT_STATISTICS_BANNED_HOSTS_DESC); $propbag->add('select_values', $select); $propbag->add('default', 'yes'); break; } return true; } function generate_content(&$title) { $title = $this->title; } function event_hook($event, &$bag, &$eventData) { global $serendipity; $hooks = &$bag->get('event_hooks'); if (isset($hooks[$event])) { switch($event) { case 'frontend_configure': if ($this->get_config('ext_vis_stat') == 'no') { return; } //checking if db tables exists, otherwise install them $tableChecker = serendipity_db_query("SELECT counter_id FROM {$serendipity['dbPrefix']}visitors LIMIT 1", true); if (!is_array($tableChecker)) { $this->createTables(); } if ((int)$this->get_config('db_indices_created', '0') == 0) { $this->updateTables(); } //Unique visitors are beeing registered and counted here. Calling function below. $sessionChecker = serendipity_db_query("SELECT count(sessID) FROM {$serendipity['dbPrefix']}visitors WHERE '".serendipity_db_escape_string(session_id())."' = sessID GROUP BY sessID", true); if (!is_array($sessionChecker) || (is_array($sessionChecker)) && ($sessionChecker[0] == 0)) { $referer = $useragent = $remoteaddr = 'unknown'; // gathering intel if ($_SERVER['REMOTE_ADDR']) { $remoteaddr = $_SERVER['REMOTE_ADDR']; } if ($_SERVER['HTTP_USER_AGENT']) { $useragent = substr($_SERVER['HTTP_USER_AGENT'], 0, 255); } if ($_SERVER['HTTP_REFERER']) { $referer = substr($_SERVER['HTTP_REFERER'], 0, 255); } $found = 0; // avoiding banned browsers if ($this->get_config('banned_bots') == 'yes') { // excludelist botagents $banned_array = array( '1' => "unknown", '2' => "bot", '3' => "slurpy", '4' => "agent 007", '5' => "ichiro", '6' => "ia_archiver", '7' => "zyborg", '8' => "linkwalker", '9' => "crawler", '10' => "python", '11' => "w3c_validator", '12' => "almaden", '13' => "topicspy", '14' => "poodle predictor", '15' => "link checker pro", '16' => "xenu link sleuth", '17' => "iconsurf", '18' => "zoe indexer", '19' => "grub-client", '20' => "spider", '21' => "pompos", '22' => "virus_detector", '23' => "bot", '24' => "Wells Search II", '25' => "Dumbot", '26' => "GeoBot", '27' => "DigExt", '28' => "Jeeves/Teoma", '29' => "FeedBurner", '30' => "Technorati", '31' => "Java/1.5.0_10", '32' => "Java/1.5.0_06", '33' => "MarsEdit", '34' => "Blogslive", '35' => "XMLRPCCocoa", '36' => "Google", '37' => "MagpieRSS", '38' => "Sphere Scout", '39' => "BlogCorpusReader", '41' => "libwww-perl", '42' => "WordPress", '43' => "ping.wordblog.de", '44' => "PEAR HTTP_Request", '45' => "Java/1.5.0_07", '46' => "BlogPulseLive(support@blogpulse.com)", '47' => "TrackBack", '48' => "Blogdimension", '49' => "Yahoo" ); foreach($banned_array AS $ban) { if (stristr($useragent, $ban) !== false) { $found = 1; break; } } } if ($found == 0){ $this->countVisitor($useragent, $remoteaddr, $referer); } } else { // Update visitor timestamp $this->updateVisitor(); } break; case 'backend_sidebar_entries': ?> get_config('max_items'); $ext_vis_stat = $this->get_config('ext_vis_stat'); if (!$max_items || !is_numeric($max_items) || $max_items < 1) { $max_items = 20; } if ($ext_vis_stat == 'yesTop') { $this->extendedVisitorStatistics($max_items); } if ($this->get_config('stat_all') == 'yes') { $first_entry = serendipity_db_query("SELECT timestamp FROM {$serendipity['dbPrefix']}entries ORDER BY timestamp ASC limit 1", true); $last_entry = serendipity_db_query("SELECT timestamp FROM {$serendipity['dbPrefix']}entries ORDER BY timestamp DESC limit 1", true); $total_count = serendipity_db_query("SELECT count(id) FROM {$serendipity['dbPrefix']}entries", true); $draft_count = serendipity_db_query("SELECT count(id) FROM {$serendipity['dbPrefix']}entries WHERE isdraft = 'true'", true); $publish_count = serendipity_db_query("SELECT count(id) FROM {$serendipity['dbPrefix']}entries WHERE isdraft = 'false'", true); $author_rows = serendipity_db_query("SELECT author, count(author) as entries FROM {$serendipity['dbPrefix']}entries GROUP BY author ORDER BY author"); $category_count = serendipity_db_query("SELECT count(categoryid) FROM {$serendipity['dbPrefix']}category", true); $cat_sql = "SELECT c.category_name, count(e.id) as postings FROM {$serendipity['dbPrefix']}entrycat ec, {$serendipity['dbPrefix']}category c, {$serendipity['dbPrefix']}entries e WHERE ec.categoryid = c.categoryid AND ec.entryid = e.id GROUP BY ec.categoryid, c.category_name ORDER BY postings DESC"; $category_rows = serendipity_db_query($cat_sql); $image_count = serendipity_db_query("SELECT count(id) FROM {$serendipity['dbPrefix']}images", true); $image_rows = serendipity_db_query("SELECT extension, count(id) AS images FROM {$serendipity['dbPrefix']}images GROUP BY extension ORDER BY images DESC"); $subscriber_count = count(serendipity_db_query("SELECT count(id) FROM {$serendipity['dbPrefix']}comments WHERE type = 'NORMAL' AND subscribed = 'true' GROUP BY email")); $subscriber_rows = serendipity_db_query("SELECT e.timestamp, e.id, e.title, count(c.id) as postings FROM {$serendipity['dbPrefix']}comments c, {$serendipity['dbPrefix']}entries e WHERE e.id = c.entry_id AND type = 'NORMAL' AND subscribed = 'true' GROUP BY e.id, c.email, e.title, e.timestamp ORDER BY postings DESC LIMIT $max_items"); $comment_count = serendipity_db_query("SELECT count(id) FROM {$serendipity['dbPrefix']}comments WHERE type = 'NORMAL'", true); $comment_rows = serendipity_db_query("SELECT e.timestamp, e.id, e.title, count(c.id) as postings FROM {$serendipity['dbPrefix']}comments c, {$serendipity['dbPrefix']}entries e WHERE e.id = c.entry_id AND type = 'NORMAL' GROUP BY e.id, e.title, e.timestamp ORDER BY postings DESC LIMIT $max_items"); $commentor_rows = serendipity_db_query("SELECT author, max(email) as email, max(url) as url, count(id) as postings FROM {$serendipity['dbPrefix']}comments c WHERE type = 'NORMAL' GROUP BY author ORDER BY postings DESC LIMIT $max_items"); $tb_count = serendipity_db_query("SELECT count(id) FROM {$serendipity['dbPrefix']}comments WHERE type = 'TRACKBACK'", true); $tb_rows = serendipity_db_query("SELECT e.timestamp, e.id, e.title, count(c.id) as postings FROM {$serendipity['dbPrefix']}comments c, {$serendipity['dbPrefix']}entries e WHERE e.id = c.entry_id AND type = 'TRACKBACK' GROUP BY e.timestamp, e.id, e.title ORDER BY postings DESC LIMIT $max_items"); $tbr_rows = serendipity_db_query("SELECT author, max(email) as email, max(url) as url, count(id) as postings FROM {$serendipity['dbPrefix']}comments c WHERE type = 'TRACKBACK' GROUP BY author ORDER BY postings DESC LIMIT $max_items"); $length = serendipity_db_query("SELECT SUM(LENGTH(body) + LENGTH(extended)) FROM {$serendipity['dbPrefix']}entries", true); $length_rows = serendipity_db_query("SELECT id, title, (LENGTH(body) + LENGTH(extended)) as full_length FROM {$serendipity['dbPrefix']}entries ORDER BY full_length DESC LIMIT $max_items"); ?>










$author_stat) { ?>
(%)




$cat_stat) { ?>




$image_stat) { ?>




$com_stat) { ?>

$com_stat) { $link_start = ''; $link_end = ''; $link_url = ''; if (!empty($com_stat['email'])) { $link_start = ''; $link_end = ''; } if (!empty($com_stat['url'])) { if (substr($com_stat['url'], 0, 7) != 'http://' && substr($com_stat['url'], 0, 8) != 'https://') { $com_stat['url'] = 'http://' . $com_stat['url']; } $link_url = ' (' . PLUGIN_EVENT_STATISTICS_OUT_LINK . ')'; } if (empty($com_stat['author'])) { $com_stat['author'] = ANONYMOUS; } ?>




$subscriber_stat) { ?>




$tb_stat) { ?>

$tb_stat) { if (empty($tb_stat['author'])) { $tb_stat['author'] = ANONYMOUS; } ?>













$length_stat) { ?>



$max_items)); ?>
extendedVisitorStatistics($max_items); } return true; break; default: return false; break; } } else { return false; } } //Statistics function updatestats($action) { global $serendipity; list($year, $month, $day) = explode('-', date('Y-m-d')); $sql = serendipity_db_query("SELECT COUNT(year) AS result FROM {$serendipity['dbPrefix']}visitors_count WHERE year='$year' AND month='$month' AND day='$day'", true); $sql_hit_update = "UPDATE {$serendipity['dbPrefix']}visitors_count SET hits = hits+1 WHERE year='$year' AND month='$month' AND day='$day'"; $sql_day_new = "INSERT INTO {$serendipity['dbPrefix']}visitors_count (year, month, day, visits, hits) VALUES ('$year','$month','$day',1,1)"; $sql_day_update = "UPDATE {$serendipity['dbPrefix']}visitors_count SET visits = visits+1, hits = hits+1 WHERE year='$year' AND month='$month' AND day='$day'"; switch($action) { case "update": if($sql['result'] >= 1) { serendipity_db_query($sql_hit_update); } else { serendipity_db_query($sql_day_new); } break; case "new": if($sql['result'] >= 1) { serendipity_db_query($sql_day_update); } else { serendipity_db_query($sql_day_new); } break; } } function updateVisitor() { global $serendipity; $this->updatestats('update'); $time = date('H:i'); $day = date('Y-m-d'); return serendipity_db_query("UPDATE {$serendipity['dbPrefix']}visitors SET time = '$time', day = '$day' WHERE sessID = '" . serendipity_db_escape_string(strip_tags(session_id())) . "'"); } function countVisitor($useragent, $remoteaddr, $referer){ global $serendipity; $thedate = date('Y-m-d'); $ip=strip_tags($remoteaddr); $ip_how_often = serendipity_db_query("SELECT COUNT(ip) AS result FROM {$serendipity['dbPrefix']}visitors WHERE ip ='$ip' and day='$thedate'", true); if($ip_how_often['result'] >=1){ $this->updatestats('update'); } else { $this->updatestats('new'); } $values = array( 'sessID' => strip_tags(session_id()), 'day' => $thedate, 'time' => date('H:i'), 'ref' => strip_tags($referer), 'browser'=> strip_tags($useragent), 'ip' => strip_tags($remoteaddr) ); serendipity_db_insert('visitors', $values); // updating the referrer-table if (strlen($referer) >= 1) { //retrieving the referrer base URL $temp_array = explode('?', $referer); $urlA = $temp_array[0]; //removing "http://" & trailing subdirectories $temp_array3 = explode('//', $urlA); $urlB = $temp_array3[1]; $temp_array4 = explode('/', $urlB); $urlB = $temp_array4[0]; //removing www $urlC = serendipity_db_escape_string(str_replace('www.', '', $urlB)); if(strlen($urlC) < 1) { $urlC = 'unknown'; } //updating db $q = serendipity_db_query("SELECT count(refs) AS referrer FROM {$serendipity['dbPrefix']}refs WHERE refs = '$urlC' GROUP BY refs", true); if ($q['referrer'] >= 1){ serendipity_db_query("UPDATE {$serendipity['dbPrefix']}refs SET count=count+1 WHERE (refs = '$urlC')"); } else { serendipity_db_query("INSERT INTO {$serendipity['dbPrefix']}refs (refs, count) VALUES ('$urlC', 1)"); } } } //end of function countVisitor // Calculate daily stats function statistics_getdailystats() { global $serendipity; list($year, $month) = explode('-', date("Y-m")); $sql = "SELECT SUM(visits) AS dailyvisit FROM {$serendipity['dbPrefix']}visitors_count WHERE day"; for ($i=1; $i<32; $i++) { $myDay = ($i < 10) ? "0" . $i : $i; $sqlfire = $sql . " = '$myDay' AND year = '$year' AND month = '$month'"; $res = serendipity_db_query($sqlfire, true); $container[$i] = $res['dailyvisit']; } return $container; } // Calculate monthly stats function statistics_getmonthlystats() { global $serendipity; $year = date("Y"); $sql = "SELECT SUM(visits) AS monthlyvisit FROM {$serendipity['dbPrefix']}visitors_count WHERE month"; for ($i=1; $i<13; $i++) { $myMonth = ($i < 10) ? "0" . $i : $i; $sqlfire = $sql . " = '$myMonth' AND year = '$year'"; $res = serendipity_db_query($sqlfire, true); $container[$i] = $res['monthlyvisit']; } return $container; } function extendedVisitorStatistics($max_items){ global $serendipity; // ---------------QUERIES for Viewing statistics ---------------------------------------------- $day = date('Y-m-d'); list($year, $month, $day) = explode('-', $day); $visitors_count_firstday = serendipity_db_query("SELECT day FROM {$serendipity['dbPrefix']}visitors ORDER BY counter_id ASC LIMIT 1", true); $visitors_count_today = serendipity_db_query("SELECT visits FROM {$serendipity['dbPrefix']}visitors_count WHERE year = '".$year."' AND month = '".$month."' AND day = '".$day."'", true); $visitors_count = serendipity_db_query("SELECT SUM(visits) FROM {$serendipity['dbPrefix']}visitors_count", true); $hits_count_today = serendipity_db_query("SELECT hits FROM {$serendipity['dbPrefix']}visitors_count WHERE year = '".$year."' AND month = '".$month."' AND day = '".$day."'", true); $hits_count = serendipity_db_query("SELECT SUM(hits) FROM {$serendipity['dbPrefix']}visitors_count", true); $visitors_latest = serendipity_db_query("SELECT counter_id, day, time, ref, browser, ip FROM {$serendipity['dbPrefix']}visitors ORDER BY counter_id DESC LIMIT ".$max_items.""); $top_refs = serendipity_db_query("SELECT refs, count FROM {$serendipity['dbPrefix']}refs ORDER BY count DESC LIMIT 20"); // ---------------STYLES for Viewing statistics ---------------------------------------------- echo ""; ?>





0) { ?> statistics_getmonthlystats(); $rep = $num; rsort($rep); $maxVisHeigh = 100/$rep[0]*2; for ($i=1; $i < 13; $i++) { if ($color == "col1") { $color ="col2"; } else { $color ="col1"; } echo ''; } ?> 'Jan', '2' => 'Feb', '3' => 'Mar', '4' => 'Apr', '5' => 'May', '6' => 'Jun', '7' => 'Jul', '8' => 'Aug', '9' => 'Sep', '10' => 'Oct', '11' => 'Nov', '12' => 'Dec'); $color = "col2"; for ($i = 1; $i < 13; $i++) { if ($color == "col1") { $color ="col2"; } else { $color ="col1"; } echo ''; } ?>
' . $num[$i]; echo '
'; echo '
'. serendipity_strftime('%b', mktime(0, 0, 0, $i, 1, 2000)) .'
0) { ?> statistics_getdailystats(); $rep = $num; rsort($rep); for ($i=1; $i < 32; $i++) { if ($color == "col1") { $color ="col2"; } else { $color ="col1"; } $maxVisHeigh = 100/$rep[0]*2; echo ''; } ?> '. $i .''; } ?>
' . $num[$i]; echo '
'; echo '


$row) { if ($color == "col1"){$color ="col2";}else{$color ="col1";} echo ""; echo "\n"; if($row['ref']!='unknown'){ echo "\n"; } if($row['ref']=='unknown'){ echo "\n"; } echo "\n"; echo "\n"; echo "\n"; } } ?>
".$row['day']." ".$row['time']."".wordwrap($row['ref'], 25, "
", 1)."
".wordwrap($row['ref'], 25, "
", 1)."
".wordwrap($row['browser'], 25, "
", 1)."
"; if ($row['ip']){ echo wordwrap(gethostbyaddr($row['ip']), 25, "\n", 1); } else { echo "--"; } echo "

$row) { if ($color == "col4") { $color ="col5"; } else { $color ="col4"; } echo ''; } } else { echo PLUGIN_EVENT_STATISTICS_EXT_TOPREFS_NONE; } ?>
'.$i++.'. '.$row['refs'].' ('.$row['count'].')
updateTables(); } //end of function createTables() function updateTables() { global $serendipity; //create indices $q = "CREATE INDEX visitorses ON {$serendipity['dbPrefix']}visitors (sessID);"; serendipity_db_schema_import($q); $q = "CREATE INDEX visitorday ON {$serendipity['dbPrefix']}visitors (day);"; serendipity_db_schema_import($q); $q = "CREATE INDEX visitortime ON {$serendipity['dbPrefix']}visitors (time);"; serendipity_db_schema_import($q); $q = "CREATE INDEX visitortimeb ON {$serendipity['dbPrefix']}visitors_count (year, month, day);"; serendipity_db_schema_import($q); $q = "CREATE INDEX refsrefs ON {$serendipity['dbPrefix']}refs (refs);"; serendipity_db_schema_import($q); $q = "CREATE INDEX refscount ON {$serendipity['dbPrefix']}refs (count);"; serendipity_db_schema_import($q); $this->set_config('db_indices_created', '1'); } function dropTables() { global $serendipity; // Drop tables $q = "DROP TABLE ".$serendipity['dbPrefix']."visitors"; $sql = serendipity_db_schema_import($q); $q = "DROP TABLE ".$serendipity['dbPrefix']."visitors_count"; $sql = serendipity_db_schema_import($q); $q = "DROP TABLE ".$serendipity['dbPrefix']."refs"; $sql = serendipity_db_schema_import($q); } //end of function dropTables function install(){ $this->createTables(); } function uninstall(){ $this->dropTables(); } } /* vim: set sts=4 ts=4 expandtab : */