<?php
// This class file is a compact version of the 2 main classes we use.
include_once( "class/plugin/pluginbase.class.php" );
include_once( "class/plugin/pluginmanager.class.php" );
include_once( PLOG_CLASS_PATH."class/dao/model.class.php" );
include_once( PLOG_CLASS_PATH."class/net/client.class.php" );
include_once( PLOG_CLASS_PATH."debug.php" );

define ("WHO_ONLINE_TIMEOUT", 360); // 2 minutes
// Define the main class as a plugin

class PluginWhoOnline extends PluginBase {
	var $clientip;
	var $tstamp;
    	function PluginWhoOnline() { // Declare some about info
		$this->PluginBase();
		$this->desc = "
<p>This plugin will allow your visitors to view how many other visitors are online at the same time. Well it actual does a bit more than that. It can also serve as a simple hit counter and record the most number of online users.<br>
It is pretty easy to use. For now if you want to configure the capture time just edit the top of the plugin. It is
set with a default of 120 seconds (2 minutes). For now it will only capture visitors in general but i also want it
to capture registered (logged in) users, views on specific entries and specific blogs. Have fun and happy hacking.<br>
<b>Note</b>: This plugin will not record information automatically. It will not count hits on pages that do not include the BlogCount function. Might be a good idea to keep it somewhere global like a side panel or footer.<br>
Examples:<br>
<b>{\$whoonline->WhoOnlineSite()}</b> - returns all users recorded over all blogs.<br>
<b>{\$whoonline->WhoOnlineBlog([id or default current])}</b> - returns all users on a specific blog.<br>
<b>{\$whoonline->WhoOnlineEntry([article id])}</b> - returns all users on a specific article.<br>
<b>{\$whoonline->WhoOnlineCustom([unique id])}</b> - returns all users on a custom entry. Like a specific template, etc<br>
<b>{\$whoonline->WhoOnlineMax([id or default current])}</b> - returns the highest number of users online for specific blog.<br>
<b>{\$whoonline->BlogCount([id or default current])}</b> - returns a blogs total number of hits.<br>
</p>";
		$this->author = "Nick Gerakines";
	}
	function register() { // initialize the class
//		print("[Debug: WhoOnline] Initilizing Class.<br>");
		$w = new WhoAreUs(); // create the secondary class object
		$t = new Timestamp(); // create a timestamp object, might be quicker to just invoke time()
		$w->createWhoTables(); // sift through and see if the tables exist
//		print("[Debug: WhoOnline] Checking Tables.<br>");
//		print("[Debug: WhoOnline] Online timeout default set to ".WHO_ONLINE_TIMEOUT." seconds.<br>");
		$timeout = $t->getUnixDate() - WHO_ONLINE_TIMEOUT; // get the timeout number
//		print("[Debug: WhoOnline] Setting timeout to $timeout.<br>");
		$this->tstamp = $t->getUnixDate();
//		print("[Debug: WhoOnline] Setting tstamp to ".$this->tstamp."<br>");
		$this->clientip = Client::getIp();
//		print("[Debug: WhoOnline] Setting clientip to ".$this->clientip.".<br>");
		$w->cleanwho($timeout);
	}
	function BlogCount($blog = -1) {
		$count = 0;
		if ($blog < 0) {$blog = $this->blogInfo->getId();}
		$w = new WhoAreUs(); // create the secondary class object
		$count = $w->gethits($blog);
		return $count;
	}
	function WhoOnlineMax($blog = -1) {
//		print("[Debug: WhoOnline->WhoOnlineMax] Running function WhoOnlineMax.<br>");
		$count = 0;
		if ($blog < 0) {$blog = $this->blogInfo->getId();}
//		print("[Debug: WhoOnline->WhoOnlineMax] Using blog $blog.<br>");
		$w = new WhoAreUs();
		$count = $w->getcount(" WHERE blog_id = $blog");
//		print("[Debug: WhoOnline->WhoOnlineMax] Getting current blog count of $count.<br>");
		$mcount = $w->getmax($blog, $count);
//		print("[Debug: WhoOnline->WhoOnlineMax] returning $mcount.<br>");
		return $mcount;
	}
	function WhoOnlineSite() { // Poll all distinct visits to the site
//		print("[Debug: WhoOnline] Running function WhoOnlineSite.<br>");
		$count = 0;
		$blog = $this->blogInfo->getId();
//		print("[Debug: WhoOnline] Setting blog to $blog.<br>");
		$w = new WhoAreUs(); // create the secondary class object
		$w->injectSQL("( `blog_id` , `timestamp` , `ip` ) VALUES ('$blog', '".$this->tstamp."', '".$this->clientip."' );");
		$count = $w->getcount("");
		return $count;
	}
	function WhoOnlineBlog ($blog = -1) { // Poll all distinct visits to specific blog
//		print("[Debug: WhoOnline] Running function WhoOnlineBlog.<br>");
		$count = 0;
//		print("[Debug: WhoOnline] Blog set to $blog.<br>");
		if ($blog < 0) {$blog = $this->blogInfo->getId();}
//		print("[Debug: WhoOnline] Blog now set to $blog.<br>");
		$w = new WhoAreUs(); // create the secondary class object
		$w->injectSQL("( `blog_id`, `timestamp` , `ip` ) VALUES ( '$blog', '".$this->tstamp."', '".$this->clientip."' );");
		$count = $w->getcount(" WHERE blog_id = $blog");
		return $count;
	}
	function WhoOnlineEntry($article) { // Poll all distinct visits to specific article in blog
//		print("[Debug: WhoOnline] Running function WhoOnlineEntry on article $article.<br>");
		$count = 0;
		$blog = $this->blogInfo->getId();
//		print("[Debug: WhoOnline] Setting blog to $blog<br>");
		$w = new WhoAreUs(); // create the secondary class object
		$w->injectSQL("( `blog_id` , `article_id` , `timestamp` , `ip` ) VALUES ( '$blog', '$article', '".$this->tstamp."', '".$this->clientip."' );");
		$count = $w->getcount(" WHERE blog_id = $blog AND article_id = $article");
		return $count;
	}
	function WhoOnlineCustom($custom){
		$count = 0;
		$blog = $this->blogInfo->getId();
		$w = new WhoAreUs(); // create the secondary class object
		$w->injectSQL("( `blog_id` , `custom_id` , `timestamp` , `ip` ) VALUES ( '$blog', '$custom', '".$this->tstamp."', '".$this->clientip."' );");
		$count = $w->getcount(" WHERE blog_id = $blog AND custom_id = $custom");
		return $count;
	}
}
// Define the datacruncher class
class WhoAreUs extends Model {
	function WhoAreUs() { // continue class schema defs
		$this->Model();
	}
	function checkTable( $tableName, $tableSchema ) { // hacked from karma plugin
		//$config = new Config();
		//$dbPrefix = $config->getValue( "db_prefix" );
		$dbPrefix = $this->getPrefix();
		$tableName = $dbPrefix.$tableName;
		// create the data dictionary and create the table if necessary
		$dict = NewPDbDataDictionary( $this->_db );
		$sqlArray = $dict->ChangeTableSQL( $tableName, $tableSchema );
		$result = $dict->ExecuteSQLArray( $sqlArray );
		if( $result == 0 )
			$this->_desc = "There was an error initializing the tables.";
	}
	function createWhoTables() { // hacked from karma plugin
		$table1 = "who_online";
		$fields1 = "blog_id I(10) NOT NULL default '-1',
			article_id I(10) NOT NULL default '-1',
			custom_id I(10) NOT NULL default '-1',
			timestamp int(15) NOT NULL default '0',
			ip varchar(40) NOT NULL";
		$this->checkTable( $table1, $fields1 );
		$table2 = "who_counts";
		$fields2 = "blogid INT DEFAULT '0' NOT NULL ,
			count INT,
			count_max INT,
			lastupdate INT(25)";
		$this->checkTable( $table2, $fields2);
		return true;		
	}
	function injectSql($dbqry) {
		$query = "INSERT INTO ".$this->getPrefix()."who_online $dbqry";
//		print("[Debug: WhoOnline] Running injection with query: $query<br>");
		$result = $this->_db->Execute( $query );
	}
	function cleanwho($timeout) {
		$query = "DELETE FROM ".$this->getPrefix()."who_online WHERE timestamp < $timeout";
//		print("[Debug: WhoOnline] Running clean with query: $query<br>");
		$result = $this->_db->Execute( $query );
		return $result;
	}
	function getcount($dbqry) {
		$query = "SELECT DISTINCT ip FROM ".$this->getPrefix()."who_online$dbqry";
//		print("[Debug: WhoOnline] Running getcount with query: $query.<br>");
		$count = 0;
		$result = $this->_db->Execute($query);
		if ($result) {
//			print("[Debug: WhoOnline] getcount success.<br>");
			$count = $result->RecordCount();
		}
//		print("[Debug: WhoOnline] returning count of $count.<br>");
		return $count;
	}
	// gethits function keeps a count of hits on any given blog.
	// We could do this several ways.
	// (1) Insert a new record for each hit and just do a record count
	// (2) Use a single row per blog and just update the count as needed
	// For time space and effort i'm going with number 1
	function gethits($blog) {
		$count = 1;
		$query = "select * from ".$this->getPrefix()."who_counts where blogid = $blog";
		$result = $this->_db->Execute($query);
		$rcount = $result->RecordCount();
		if ($rcount > 0) {
			$row = $result->FetchRow();
			$count = $row["count"] + 1;
			// 1+ rows existed, do update
			$query = "UPDATE ".$this->getPrefix()."who_counts SET count = $count WHERE blogid = $blog";
		} else {
			// 0 rows existed, do insert.
			$query = "INSERT INTO ".$this->getPrefix()."who_counts ( blogid, count) VALUES ('$blog', '$count');";
		}
		$result = $this->_db->Execute($query);
		return $count;
	}
function getmax($blog, $cur_count){
		// see if the row is set or not
		$count = 0;
		$query = "Select * from ".$this->getPrefix()."who_counts where blogid = $blog";
//		print("[Debug: WhoOnline->getmax] Running test Query: <b>$query</b>.<br>");
		$result = $this->_db->Execute($query);
		$rcount = $result->RecordCount();
//		print("[Debug: WhoOnline->getmax] Test query yields $rcount rows.<br>");
		if ($rcount > 0) {
//			print("[Debug: WhoOnline->getmax] Updating record. <br>");
			$row = $result->FetchRow();
			$count = $row["count_max"];
//			print("[Debug: WhoOnline->getmax] Current max count at $count.<br>");
			if ($cur_count > $count) {
				$count = $cur_count;
				$query = "UPDATE ".$this->getPrefix()."who_counts SET count_max = $count WHERE blogid = $blog";
//				print("[Debug: WhoOnline->getmax] Updating query with $query.<br>");
				$result = $this->_db->Execute($query);
				if ($result) {
//					print("[Debug: WhoOnline->getmax] Update success with query: $query.<br>");
				}
			}
		} else {
			$count = $cur_count;
//			print("[Debug: WhoOnline->getmax] Inserting new record with max count at $cur_count.<br>");
			$query = "INSERT INTO ".$this->getPrefix()."who_counts ( blogid, count_max) VALUES ('$blog', '$count');";
//			print("[Debug: WhoOnline->getmax] Inserting new record with query: $query.<br>");
			$result = $this->_db->Execute($query);
			if ($result) {
//					print("[Debug: WhoOnline->getmax] Insert success with query: $query.<br>");
			}

		}
		return $count;
	}
}
PluginManager::registerPlugin( "whoonline", "PluginWhoOnline" );
?>
