<?php
include_once ("_dirinfo.php");
include_once (PATH_TO_ROOT . "init.php");
include (PATH_TO_ROOT . "webcati/_ajax/liveUpdate/SqlFileTransaction.class.php");

/**
 * starts an update of client, checks version of client, runs remote scripts on client
 * this class runs on server
 */

class Update {
	
	private $project_id;
	private $interv_id;
	private $srv_db;
	private $rip; //remote client IP 
	private $cli_ver;
	private $curr_ver; //current updating version
	private $iserror;
	private $errormsg;
	
	/**
	 * set main paramters
	 *
	 * @param integer $project  project ID
	 * @param integer $interv   interviewer id
	 * @param database connection $db  connection from class db, set in init.php
	 */
	function __construct($project, $interv, $db) {
		$this->project_id = $project;
		$this->interv_id = $interv;
		$this->srv_db = $db;
		$this->srv_db->ChangeDatabase ( DB_WARPIT_LIVEUPDATE );
		$this->rip = $_SERVER ['REMOTE_ADDR'];
		$this->iserror = 0;
		$this->errormsg = "";
	}
	/**
	 * gets client version and sets cli_ver in this class
	 *
	 */
	function getClientV() {
		//get IP from client in all possible ways ...
		if (getenv ( "HTTP_CLIENT_IP" ) && strcasecmp ( getenv ( "HTTP_CLIENT_IP" ), "unknown" ))
			$rip = getenv ( "HTTP_CLIENT_IP" );
		elseif (getenv ( "HTTP_X_FORWARDED_FOR" ) && strcasecmp ( getenv ( "HTTP_X_FORWARDED_FOR" ), "unknown" ))
			$rip = getenv ( "HTTP_X_FORWARDED_FOR" );
		elseif (getenv ( "REMOTE_ADDR" ) && strcasecmp ( getenv ( "REMOTE_ADDR" ), "unknown" ))
			$rip = getenv ( "REMOTE_ADDR" );
		elseif (isset ( $_SERVER ['REMOTE_ADDR'] ) && $_SERVER ['REMOTE_ADDR'] && strcasecmp ( $_SERVER ['REMOTE_ADDR'], "unknown" ))
			$rip = $_SERVER ['REMOTE_ADDR'];
		else {
			$this->errormsg = "Ne morem pridobiti IP clienta.";
			$this->iserror = 1;
		}
		$this->cli_ver = $this->callRemoteFile ( "http://$this->rip/warpitDevelopment/webcati/_ajax/liveUpdate/checkVersion.php" );
	}
	
	
	/**
	 * runs remote file on client and gets its return(result) in buffer
	 *
	 * @param string $url url to remote script
	 * @return string result of executed file 
	 */
	function callRemoteFile($url) { //poženem skripto na clientu in kar vrne, preberem v buffer
		$buffer = "";
		$handle = @fopen ( $url, "r" );
		if ($handle) {
			while ( ! feof ( $handle ) ) {
				$buffer = $buffer . fgets ( $handle, 4096 );
			}
			fclose ( $handle );
			return trim ( $buffer ); // buffer oklestim raznih \t\n\r, ..., ki(če) se pripnejo nanj
		}
		$this->errormsg = "Napaka pri branju bufferja!";
		$this->iserror = 1;
	}
	
	/**
	 * checks if the version to update exists and transfers it to client
	 *
	 */
	function transfer() {//echo $this->cli_ver;
		$result = $this->srv_db->SQLexecute ( "SELECT DISTINCT file_program_ver AS verzija FROM _LiveUpdateVersion WHERE file_program_ver > $this->cli_ver AND active=1" );
		while ( $verzija = $this->srv_db->fetchAssoc ( $result ) ) {
			$this->curr_ver = $verzija ["verzija"];
			//echo $this->curr_ver;
			if ($this->srv_db->IsError ()) {
				$this->errormsg = $this->srv_db->GetError ();
				$this->iserror = 1;
				break;
			}
			if (file_exists ( (WARPIT_LIVEUPDATE_ZIPVERSION . "version_" . $verzija ["verzija"] . ".zip") ) && $this->isError () == 0) {
				$rez = $this->callRemoteFile ( "http://$this->rip/warpitDevelopment/webcati/_ajax/liveUpdate/" . "transferZip.php?v=" . $verzija ["verzija"] . "&pathOnServer=" . WARPIT_LIVEUPDATE_ZIPVERSION ); //pokličem php file na clientu, ki izvrši SSH prenos iz serverja na client in razpakira zip
				if ($rez != "ok") // if there was an error at transfer, break and output error
{
					$this->errormsg = $rez;
					$this->iserror = 1;
					break;
				}//runs remote file on client, which executes statements from XMl file of the current version and increments version on client 
				$rez = $this->callRemoteFile ( "http://$this->rip/warpitDevelopment/webcati/_ajax/liveUpdate/" . "versionUp.php?v=" . $verzija ["verzija"] ); //pokličem php file na clientu, ki dvigne verzijo clienta in izvede sql stavke
				if ($rez != "ok") {
					$this->errormsg = $rez;
					$this->iserror = 1;
					break;
				}
				echo "<font color='#3366FF'>Transfered version: " . $verzija ["verzija"] . " </font><br>";
			} else {
				$this->errormsg = "Version " . $verzija ["verzija"] . " does not exist on server!";
				$this->iserror = 1;
				break;
			}
		}
	}
	
	/**
	 * runs remote file on client which generates sql file and transfers sql file to server and executes statements 
	 *
	 */
	function transferQuestionaries() {
		$rez = $this->callRemoteFile ( "http://$this->rip/warpitDevelopment/webcati/_ajax/liveUpdate/" . "transferSql.php?pathOnServer=" . WARPIT_LIVEUPDATE_ZIPVERSION . "SqlStatementsForServer/&proj_id=" . $this->project_id . "&interv_id=" . $this->interv_id ); 
		if ($rez != "ok") { // if there was an error, report ...
			//echo "<font color='#FF0033'>" . $this->errormsg = $rez . "</font><br>";
			$this->iserror = 1;
			$this->errormsg = $rez;
		} else { //execute sql statements(if any), which came from client
			if (file_exists ( (WARPIT_LIVEUPDATE_ZIPVERSION . "SqlStatementsForServer/quest_" . $this->project_id . "_" . $this->interv_id . ".sql") )) {
				$questionarie = new sqlFileTransaction ( (WARPIT_LIVEUPDATE_ZIPVERSION . "SqlStatementsForServer/quest_" . $this->project_id . "_" . $this->interv_id . ".sql"), $this->srv_db ); 
				$questionarie->doQuery ();
				if ($questionarie->iserror ()) {
					$this->srv_db->ChangeDatabase ( DB_WARPIT_LIVEUPDATE );
					$this->srv_db->SQLexecute ( "INSERT INTO questionary_log (ID,interv_id,proj_id,time_update,error_message) VALUES(null," . $this->interv_id . "," . $this->project_id . ",now(),'" . addslashes ( $questionarie->getError () ) . "')" );
					$this->errormsg = $questionarie->getError ();
					$this->iserror = 2;
				} else {
					unlink ( WARPIT_LIVEUPDATE_ZIPVERSION . "SqlStatementsForServer/quest_" . $this->project_id . "_" . $this->interv_id . ".sql" );
				}
			}
		}
	}
	
	/**
	 * writes update error to database on server
	 *
	 */
	function writeLogToServer() {
		$this->srv_db->ChangeDatabase ( DB_WARPIT_LIVEUPDATE );
		$this->srv_db->SQLexecute ( "INSERT INTO liveUpdate_log(ID,interv_id,version,time_update,error_message) VALUES(null, " . $this->interv_id . ", " . $this->curr_ver . ", now(), '" .addslashes($this->getError ()) . "') ON DUPLICATE KEY UPDATE error_message=VALUES(error_message),time_update=VALUES(time_update) " );
	}
	
	/**
	 * writes update error to database on client
	 *
	 */
	function writeLogToClient() {
		$rez = $this->callRemoteFile ( "http://$this->rip/warpitDevelopment/webcati/_ajax/liveUpdate/writeErrLogUpdate.php?v=" . $this->curr_ver . "&interv_id=" . $this->interv_id . "&err=" . str_replace(" ","+", $this->getError ()) );
		if ($rez != "ok") {
			$this->errormsg = $rez;
			$this->iserror = 1;
			echo $rez;
		}
	}
	
	/**
	 * returns error number
	 *
	 * @return integer 
	 */
	function isError() {
		return $this->iserror;
	}
	
	/**
	 * returns error message
	 *
	 * @return string
	 */
	function getError() {
		return $this->errormsg;
	}

}
//first two parameters for "Update" are projectID and userID
$update = new Update ( 5, 2, $db );
$update->getClientV (); //gets client version
if (! $update->isError ())
	$update->transfer ();
	//transfer and unzip version package on client
if (! $update->isError ())
	$update->transferQuestionaries ();
	//transfer questionaries (SQL file with sql statements) and execute it 
if ($update->isError () == 1) {
	echo "<font color='#FF0033'>" . $update->getError () . "</font><br>";
	$update->writeLogToServer ();  //if there was an error write to log on server and client
	$update->writeLogToClient ();
} elseif ($update->isError () == 2) {// inform user specially if there was an error at questionaries
	echo "<font color='#FF0033'>Error updating questionaries: " . $update->getError () . "</font><br>";
}
else echo "<font color='#3366FF'>Computer is up to date!</font><br>"; 
?>
