<?php
#	* Records Node Inforatmion in Database
#	* Uses Workgroup as Group.
#	* If "DetectNodeNumber" is turned on.  The Node ID will be created from a combination of the Group Number (Generated from the vnc_groups table)
#		and the Node number in the computer name after the last hyphen "NODE-02".  So if the group DM is "1" the node ID is 000102.
# * Automatic NodeID's that are generated from the number counter (If "DetectNodeNumber" is set to false) are taken from 99999999 counting backwards.
# * If Matching computer UniqueComputerID is found in the database then that record is used and the data is overwritten/updated.
# * If Matching NodeID is found in the Database then that record is used and the data is overwritten/updated.  (This is check after the UniqueComputerID does not match)
# * Preceeding Zero's "00023" are ignored by the viewer and repeater at the time of the connection.  Putting them there or not there have no effect other than visual.

/*
Variables in Computer Node List
%ComputerType% = W - Workstation | L - Laptop | M - MultiFunction | S - Server


*/

	error_reporting(E_ALL);
	ini_set('display_errors', 1);

	$bDebug = False;

	$Settings['DB_Host'] = "MySQL";
	$Settings['DB_User'] = "dm_dm";
	$Settings['DB_Pssword'] = "stupidputty";
	$Settings['DB_Name'] = "DesktopMasters.com";

	$aTemplateVariables["Title"] = "Desktop Masters Computers";

	$Settings['GroupResults'] = False; //> Toggle the grouping of the results.  False means no groups, just a flat list.
	$Settings['GroupResultsLimit'] = 3; //> Will group any results equal to or larger than this number.  Otherwise the results go into RogueNodesList.
	$Settings['RogueNodesListName'] = "Individual Workstations"; //> Will group any results equal to or larger than this number.  Otherwise the results go into a single container.
	$Settings['OrderNodesBy'] = "ComputerName"; // Padding of zeros's in front of the Group's Number.
	$Settings['GroupPadding'] = 4; // Padding of zeros's in front of the Group's Number.
	$Settings['PathToLauncherFiles'] = "uvnc";
	$Settings['ViewerURL'] = "dm-07:55900";

	OpenDatabase();
	DisplayPage();
	
	$Settings['hDB'] -> Close();

exit;
		
//#########################################################################################################		
		
	$GroupID = GetGroupID($Group);
		If ($bDebug) { Echo  "Found GroupID=".$GroupID."\r\n"; }
	$NodeID = RecordNodeID($aComputerData, $GroupID);
	SaveLauncherFile($aComputerData);


//-> Give NodeID for the client connection (The Necessary Output)
	Echo "The NodeID is ".$NodeID;
	Exit;


#------------------------------------------------------------------------------------
Function OpenDatabase() {
	Global $bDebug, $Settings;
	
	$hDB = new MySQLi($Settings["DB_Host"], $Settings['DB_User'], $Settings['DB_Pssword'], $Settings['DB_Name'], 3306);
	$Settings['hDB'] = $hDB;
		if ($Settings['hDB'] -> connect_error) {
			die("Connection failed: " . $Settings['hDB'] -> connect_error . "\r\n");
		}
		If ($bDebug) { Echo "Host Connect Info: " . $Settings['hDB'] -> host_info . "<br />\r\n"; }
}
#------------------------------------------------------------------------------------
Function RecordNodeID($aComputerData, $GroupID) {
	Global $bDebug, $Settings, $NodeID, $NodeDisplayName, $iNodeRecordID;

	$UniqueComputerID = $aComputerData['UniqueComputerID'];
	$ComputerName = $aComputerData['ComputerName'];
	$NodeNumber = "";
	$qSQL = "";
		
// Build NodeID
	If ($NodeID == "") { //Checks to see if a NodeID was submitted.
		If ($bDebug) { Echo  "Submitted NodeID is empty.  Trying to build a new one\r\n"; }
		If (($aComputerData['DetectNodeNumber']) AND (StrPos($ComputerName, "-") !== False)) { // If the Detect node number switch is turned on and computer name has a hyphen it will read the number hafter the hyphen so "NODE-02" would return "02".
			If ($bDebug) { Echo  "NodeID is empty and computer name has a hyphen.  Building a new one...\r\n"; }
			$aComputerName = Explode("-", $ComputerName);
			If (Is_Numeric($aComputerName[Count($aComputerName)-1])) {
				$NodeNumber = $aComputerName[Count($aComputerName)-1];
				$NodeID =  Str_Pad($GroupID, $Settings['GroupPadding'], "0", STR_PAD_LEFT).$NodeNumber;
				If ($bDebug) { Echo  "Built NodeID: ".$NodeID."\r\n"; }
			}
		} Else { // Get Generic NodeID Number
			$Result = $Settings['hDB']->Query('SELECT * FROM vnc_options  WHERE OptionName="NextGenericNodeID";'); // Get next generic NodeID number from the Database.
			$RowsReturned = $Result -> num_rows;
			If ($bDebug) { Echo  "Rows Returned from vnc_options: ". $RowsReturned ."\r\n"; }
			$Result -> Data_Seek(0);
			$Row = $Result -> Fetch_Assoc();
			If ($RowsReturned == 0) { // If there is no id 1 make a new one.  (First time run?)
				If ($bDebug) { Echo  "No Generic NodeID number found in the database.  Creating a new line\r\n"; }
				$NodeID = 999999999;
				$qSQL = "INSERT INTO vnc_options (OptionName, Value) VALUES ('NextGenericNodeID', '". ($NodeID - 1) ."');"; // Create new/first record with next node ID.
			} Else {
				$NodeID = $Row['Value'];
				If ($bDebug) { Echo  "Found Generic Node ID '".$NodeID."' in the database.. \r\n"; }
				$qSQL = "UPDATE vnc_options SET Value=". ($NodeID - 1) ." WHERE id=".$Row['id'].";"; // Create new/first record with next node ID.
			}
			If ($Settings['hDB'] -> Query($qSQL) !== True) {
				Echo "Error: " . $qSQL . "\r\n" . $Settings['hDB'] -> error . "\r\n";
			}
		}
	} Else {
		If ($bDebug) { Echo  "'".$NodeID."' Was previously submitted.  Using this instead of creating one.\r\n"; }
	}

	$Result = $Settings['hDB'] -> Query('SELECT * FROM vnc_nodes WHERE UniqueComputerID LIKE "'.$UniqueComputerID.'";');
	If(! $Result ) {
  	Die('(1) Could not get data: ' . mysql_error()."\r\n");
	}

	$NodeDisplayName = GetNodeDisplayName($aComputerData);
		
	$Result -> Data_Seek(0);
	$Row = $Result -> Fetch_Assoc();

// Compare to existing records or make a new one.
	If ($Row['UniqueComputerID'] == "") {
		If ($bDebug) { Echo  "No UniqueComputerID in records found\r\n"; }
 		If ($NodeID != "")	{
			If ($bDebug) { Echo  "NodeID has a value to work with\r\n"; }
			If ($bDebug) { Echo  'Searching for records with: "'.$NodeID.'"'."\r\n"; }
			$Result = $Settings['hDB'] -> Query('SELECT * FROM vnc_nodes WHERE NodeID="'.$NodeID.'";');
				If(! $Result ) {
	  			Die('(2) Could not get data: ' . mysql_error()."\r\n");
				}
			$Result -> Data_Seek(0);
			$Row = $Result -> Fetch_Assoc();
			If ($Row['NodeID'] <> $NodeID) {
				If ($bDebug) { Echo  "No NodeID Value Found\r\n"; }
				$qSQL = "INSERT INTO vnc_nodes (id, NodeID, ComputerName, Location, ComputerType, DisplayName, NodeGroup, DomainName, UniqueComputerID) VALUES (0, '".$NodeID."', '".$aComputerData['ComputerName']."', '".$aComputerData['ComputerLocation']."', '".$aComputerData['ComputerType']."', '".Str_Replace("'", "\\'", $aComputerData['ComputerDescription'])."', '".$aComputerData['DomainName']."', '".$aComputerData['DomainName']."', '".$aComputerData['UniqueComputerID']."');";
			} Else {
				If ($bDebug) { Echo  "Found a matching NodeID Value: ".$Row['NodeID']."\r\n"; }
				$qSQL = "UPDATE vnc_nodes SET NodeID='".$NodeID."', ComputerName='".$aComputerData['ComputerName']."', Location='".$aComputerData['ComputerLocation']."', ComputerType='".$aComputerData['ComputerType']."', DisplayName='".Str_Replace("'", "\\'", $aComputerData['ComputerDescription'])."', NodeGroup='".$aComputerData['DomainName']."', DomainName='".$aComputerData['DomainName']."', UniqueComputerID='".$aComputerData['UniqueComputerID']."' WHERE id=".$Row['id'].";";
			}
		} Else {
			If ($bDebug) { Echo  "Submitted NodeID is empty.  Adding new record\r\n"; }
			$qSQL = "INSERT INTO vnc_nodes (id, NodeID, ComputerName, Location, ComputerType, DisplayName, NodeGroup, DomainName, UniqueComputerID) VALUES (0, '".$NodeID."', '".Str_Replace("'", "\\'", $aComputerData['ComputerDescription'])."', '".$aComputerData['ComputerName']."', '".$aComputerData['DomainName']."', '".$aComputerData['DomainName']."', '".$aComputerData['UniqueComputerID']."');";
		}
	} Else {
		If ($bDebug) { Echo  "UniqueComputerID matches database.  Updating Record\r\n"; }
		$qSQL = "UPDATE vnc_nodes SET NodeID='".$NodeID."', ComputerName='".$aComputerData['ComputerName']."', Location='".$aComputerData['ComputerLocation']."', ComputerType='".$aComputerData['ComputerType']."', DisplayName='".Str_Replace("'", "\\'", $aComputerData['ComputerDescription'])."', NodeGroup='".$aComputerData['DomainName']."', DomainName='".$aComputerData['DomainName']."', UniqueComputerID='".$aComputerData['UniqueComputerID']."' WHERE id=".$Row['id'].";";
	}

	If ($Settings['hDB'] -> Query($qSQL) === True) {
		If ($bDebug) { Echo  "New record created/updated successfully\r\n"; }
		Return $NodeID;
	} Else {
		Echo "Error: " . $qSQL . "\r\n" . $Settings['hDB'] -> error . "\r\n";
	}
}

#########################################
Function GetGroupID($Group) {
	Global $bDebug, $Settings;
		
	$Result = $Settings['hDB'] -> Query('SELECT * FROM vnc_groups WHERE name LIKE "'.$Group.'";');
		If(! $Result ) {
	  	Die('(3) Could not get data: ' . mysql_error()."\r\n");
		}
	$RowsReturned = $Result -> num_rows;
	If ($bDebug) { Echo  "Rows Returned from vnc_groups: ". $RowsReturned ."\r\n"; }
	$Result -> Data_Seek(0);
	$Row = $Result -> Fetch_Assoc();
	$Id = $Row['id'];
	If ($Id > 0) {
		Return $Id;
	}
		
	$qSQL = "INSERT INTO vnc_groups (id, name, displayname) VALUES (0, '".$Group."', '".$Group."');";
	If ($Settings['hDB'] -> Query($qSQL) === True) {
#		If ($bDebug) { Echo  "New record created successfully\r\n"; }
	} Else {
		Echo "Error: " . $qSQL . "\r\n" . $Settings['hDB'] -> error . "\r\n";
	}

	$Result = $Settings['hDB'] -> Query('SELECT * FROM vnc_groups WHERE name LIKE "'.$Group.'";');
		If(! $Result ) {
	  	Die('(4) Could not get data: ' . mysql_error()."\r\n");
		}
	$Result -> Data_Seek(0);
	$Row = $Result -> Fetch_Assoc();
	$Id = $Row['id'];
	If ($Id > 0) {
		Return $Id;
	}

			
	Return "X";
#	while($row = mysql_fetch_array($Results, MYSQL_ASSOC)) {			
#		Print_R($Row);
#		echo "EMP ID :{$row['emp_id']}  <br> ".			         "EMP NAME : {$row['emp_name']} <br> ".			         "EMP SALARY : {$row['emp_salary']} <br> ".			         "--------------------------------<br>";
#	}
}

#########################################
Function ConvertArrayToVariables($aArray) {
	$aNewArray = Array();
	$aKeys = Array_Keys($aArray);

	For ($iRow = 0; $iRow < Count($aArray); $iRow++) {
		$aNewArray["%".$aKeys[$iRow]."%"] = $aArray[$aKeys[$iRow]];
	}
#	Print_R($aArray);
#	Print_R($aNewArray);
	Return $aNewArray;
}


Function GetNodeDisplayNameTemplate() {
	Global $bDebug, $Settings, $NodeID;

	If (IsSet($Settings['NodeDisplayNameTemplate'])) {
		$sDisplayNameTemplate = $Settings['NodeDisplayNameTemplate'];
	} Else {
		$Result = $Settings['hDB'] -> Query('SELECT * FROM vnc_options WHERE OptionName="DisplayNameTemplate";');
			If(! $Result ) {	Die('(5) Could not get data: ' . mysql_error()."\r\n");	}
		$RowsReturned = $Result -> num_rows;
		If ($RowsReturned > 0) {
			$Result -> Data_Seek(0);
			$Row = $Result -> Fetch_Assoc();
			$sDisplayNameTemplate = $Row['Value'];
		} Else {
			$sDisplayNameTemplate = "%DomainName%.%ComputerName% - %ComputerDescription% (%NodeID%)"; //-> Default value to set because no option was found.
			If ($Settings['hDB'] -> Query("INSERT INTO vnc_options (OptionName, Value) VALUES ('NodeDisplayNameTemplate', '".$sDisplayNameTemplate."');") !== True) {
				Echo "Error: " . $qSQL . "\r\n" . $Settings['hDB'] -> error . "\r\n";
			}
		}
	}
	
	Return $sDisplayNameTemplate;
}


Function GetNodeDisplayName($aComputerData) {
	Global $bDebug, $Settings, $NodeID;

	If (IsSet($Settings['NodeDisplayNameTemplate'])) {
		$sDisplayNameTemplate = $Settings['NodeDisplayNameTemplate'];
	} Else {
		$Result = $Settings['hDB'] -> Query('SELECT * FROM vnc_options WHERE OptionName="DisplayNameTemplate";');
			If(! $Result ) {	Die('(5) Could not get data: ' . mysql_error()."\r\n");	}
		$RowsReturned = $Result -> num_rows;
		If ($RowsReturned > 0) {
			$Result -> Data_Seek(0);
			$Row = $Result -> Fetch_Assoc();
			$sDisplayNameTemplate = $Row['Value'];
		} Else {
			$sDisplayNameTemplate = "%DomainName%.%ComputerName% - %ComputerDescription% (%NodeID%)"; //-> Default value to set because no option was found.
			If ($Settings['hDB'] -> Query("INSERT INTO vnc_options (OptionName, Value) VALUES ('NodeDisplayNameTemplate', '".$sDisplayNameTemplate."');") !== True) {
				Echo "Error: " . $qSQL . "\r\n" . $Settings['hDB'] -> error . "\r\n";
			}
		}
	}
	
	$NodeDisplayName = Str_iReplace("%NODEID%", $NodeID, $sDisplayNameTemplate);
	$aKeys = Array_Keys(ConvertArrayToVariables($aComputerData));
	$NodeDisplayName = Str_iReplace($aKeys, $aComputerData, $NodeDisplayName);
		
	Echo "Display Name: " . $NodeDisplayName . "\r\n";
#	Echo Print_R($aKeys)."\r\n";

	Return $NodeDisplayName;
}

#########################################
Function SaveLauncherFile($aComputerData) {
	Global $bDebug, $Settings, $NodeID, $NodeDisplayName;

#	$hVNCFile = FOpen($Settings['PathToLauncherFiles']."/".$NodeDisplayName.".vnc", "w");
	$sVNCFile = $Settings['PathToLauncherFiles']."/".Str_Replace("/", "-", $NodeDisplayName).".vnc";
			
	If (! File_Exists(DirName($Settings['PathToLauncherFiles']))) {
		MkDir(DirName($Settings['PathToLauncherFiles']), 0776, True);
	}

	Echo "Deleteing ".$Settings['PathToLauncherFiles']."/*(".$NodeID.")*\n";
	ForEach (Glob($Settings['PathToLauncherFiles']."/*(".$NodeID.")*") as $FileName) {
		Echo "Deleting $FileName"."\n";
		UnLink($FileName);
	}

	If (! File_Exists($sVNCFile)) {
		Copy($Settings['PathToLauncherFiles']."/Default.vnc", $sVNCFile);
	}

	INI_Write($sVNCFile, "connection", "host", "ID");
	INI_Write($sVNCFile, "connection", "port", $NodeID);
	If (IsSet($Settings['ViewerURL'])) {
		Echo 'Writing Viewer Config Files with: "'.$Settings['ViewerURL'].'"'."\r\n";
		$aViewerURL = Explode(":", $Settings['ViewerURL']);
		INI_Write($sVNCFile, "connection", 'proxyhost', $aViewerURL[0]);
		INI_Write($sVNCFile, "connection", 'proxyport', $aViewerURL[1]);
	} Else {
		If (IsSet($aComputerData['ProxyHost'])) { INI_Write($sVNCFile, "connection", 'proxyhost', $aComputerData['ProxyHost']); }
		If (IsSet($aComputerData['ProxyPort'])) { INI_Write($sVNCFile, "connection", 'proxyport', $aComputerData['ProxyPost']); }
	}
}

#########################################
Function INI_Write($FileName, $Section, $Key, $Value)
{
#	echo Shell_Exec("ls -hal ".$FileName)."\r\n";
#	echo Shell_Exec("cat ".$FileName)."\r\n";
	$aIni = Parse_Ini_File($FileName, True); //-> Read File and convert to array
	
	If (IsSet($aIni[$Section][$Key])) { $aIni[$Section][$Key] = $Value; } //-> Set Value if in file.

	$hFile = FOpen($FileName, "w"); //-> Open File for output
	While (List($xSection, $aKeys) = Each($aIni)) { //-> Write File Data back to file
		FWrite($hFile, "[".$xSection."]\r\n");
		While (List($xKey, $xValue) = Each($aKeys)) {
			FWrite($hFile, $xKey."=".$xValue."\r\n");
		}
	}
	FClose($hFile);
}

#########################################
Function SavePostDataExtraInfo($aComputerData)
{
	$aKeys = Array_Keys($aComputerData);

	For ($iRow = 0; $iRow < Count($aComputerData); $iRow++) {
		$qSQL = "";
		$qSQL = $qSQL . "";
		$aNewArray["%".$aKeys[$iRow]."%"] = $aArray[$aKeys[$iRow]];
	}
#	Print_R($aArray);
#	Print_R($aNewArray);
	Return $aNewArray;
}

Function GetHTML($FileName) {
#> Reads HTML template and returns the data

	$hFile = FOpen($FileName, "r") or die("Unable to open file! - ".$FileName);
	$HTML = FRead($hFile, FileSize($FileName));
	FClose($hFile);
	
	Return $HTML;
}


Function DisplayPage() {
	Global $bDebug, $Settings, $aTemplateVariables;

	$aTemplateVariableKeys = Array_Keys(ConvertArrayToVariables($aTemplateVariables));

	Echo '<!doctype html5>';
	Echo '<html lang="en">';
	Print GetHTML("Templates/header.html");

	$sBody = GetHTML("Templates/body.html");
	$sContainer = GetHTML("Templates/container.html");
	$sNodeGroupTemplate = GetHTML("Templates/nodegroup.html");
	$sNodeListTemplate = GetHTML("Templates/nodelist.html");
	$sNodeListWrapper =  GetHTML("Templates/nodelistwrapper.html");
	$sNodeDisplayNameTemplate = $Settings['NodeDisplayNameTemplate'];
	Print "Template: " . $sNodeDisplayNameTemplate . "<br />\n";
	$sComputerList = "";
	$sRogueNodesList = "";
	$bShowGroupTitles = False;
	$Groups = Array();

	If ($Settings['GroupResults']) {
		$GroupsFromDB = $Settings['hDB'] -> Query('SELECT name,displayname FROM vnc_groups WHERE Visible LIKE "Y" ORDER BY name ASC;');
		While ($GroupRow = MySQLi_Fetch_Array($GroupsFromDB)) {
			$NodesFromDB = $Settings['hDB'] -> Query('SELECT * FROM vnc_nodes WHERE NodeGroup LIKE "'.$GroupRow['name'].'" AND Visible LIKE "Y" ORDER BY '.$Settings['OrderNodesBy'].' ASC;');
			If ($NodesFromDB->num_rows > 0) {
				$sNodeList = ""; #> Rest Node List
				While ($NodeRow = MySQLi_Fetch_Array($NodesFromDB)) {
					$sNodeDisplayName = Str_iReplace(Array_Keys(ConvertArrayToVariables($NodeRow)), $NodeRow,  $sNodeDisplayNameTemplate);
					$sNodeListRow = Str_IReplace("%NodeDisplayName%", $sNodeDisplayName, $sNodeListTemplate);
					$sNodeList .= Str_iReplace(Array_Keys(ConvertArrayToVariables($NodeRow)), $NodeRow,  $sNodeListRow);
				}
				$sNodeGroup = Str_iReplace("%GroupName%", $GroupRow['name'], Str_iReplace("%GroupDisplayName%", $GroupRow['displayname'], $sNodeGroupTemplate));
				$sNodeListWrapped = Str_iReplace("%NodeList%", $sNodeList, $sNodeListWrapper); #> Add Group with Nodes to the ComputerList
				If ($NodesFromDB->num_rows >= $Settings['GroupResultsLimit']) {
					$sNodeGroup = Str_iReplace("%NodeListWrapper%", $sNodeListWrapped, $sNodeGroup); #> Add Group with Nodes to the ComputerList
					$sComputerList .= Str_iReplace("%NodeList%", $sNodeList, $sNodeGroup); #> Add Group with Nodes to the ComputerList
				} Else {
					$sRogueNodesList .= $sNodeList;
				}
			}
		}
		$sRogueNodesList = Str_iReplace("%NodeList%", $sRogueNodesList, $sNodeListWrapper); #> Add Group with Nodes to the ComputerList
		$sRogueNodesGroup = Str_iReplace("%GroupDisplayName%", $Settings['RogueNodesListName'], $sNodeGroupTemplate);
		$sRogueNodesGroup = Str_iReplace("%NodeListWrapper%", $sRogueNodesList, $sRogueNodesGroup); #> Add Group with Nodes to the ComputerList
		$sContainer = Str_iReplace("%ROGUENODESLIST%", $sRogueNodesGroup, $sContainer); #> Insert Computer List into Container
	} Else {
		$sNodeList = ""; #> Rest Node List
		$NodesFromDB = $Settings['hDB'] -> Query('SELECT * FROM vnc_nodes WHERE Visible LIKE "Y" ORDER BY '.$Settings['OrderNodesBy'].' ASC;');
		If ($NodesFromDB->num_rows > 0) {
			While ($NodeRow = MySQLi_Fetch_Array($NodesFromDB)) {
				$sNodeDisplayName = Str_iReplace(Array_Keys(ConvertArrayToVariables($NodeRow)), $NodeRow,  $sNodeDisplayNameTemplate);
				$sNodeListRow = Str_IReplace("%NodeDisplayName%", $sNodeDisplayName, $sNodeListTemplate);
				$sNodeList .= Str_iReplace(Array_Keys(ConvertArrayToVariables($NodeRow)), $NodeRow,  $sNodeListRow);
#				$sNodeList .= Str_iReplace(Array_Keys(ConvertArrayToVariables($NodeRow)), $NodeRow,  $sNodeListTemplate);
			}
		}
		$sNodeListWrapped = Str_iReplace("%NodeList%", $sNodeList, $sNodeListWrapper); #> Add Group with Nodes to the ComputerList
		$sComputerList .= Str_iReplace("%NodeList%", $sNodeList, $sNodeListWrapped); #> Add Group with Nodes to the ComputerList
	}

		
	$sContainer = Str_iReplace("%COMPUTERLIST%", $sComputerList, $sContainer); #> Insert Computer List into Container
	$sContainer = Str_iReplace("%ROGUENODESLIST%", "", $sContainer); #> If no Rogue List it removes the tag
	$sBody = Str_iReplace("%CONTAINER%", $sContainer, $sBody); #> Insert Container Into Body
	$sBody = Str_iReplace($aTemplateVariableKeys, $aTemplateVariables, $sBody); #> Replaces all variables in the template

	Print $sBody;
	Print GetHTML("Templates/footer.html");

	Return;
}

?>