<?php
/*<outscirt><version>20201229</version></outscirt>*/

/**********
Base variables
**********/
$O__PT = "";
$O__AT = "";
$O__ATcontainerTag = "";
$O__ATcontainerAttributes = "";
$O__PTATinputs = array("");
$O__layout = "";
$O__theme = "";
$O__pathPThead = "";
$O__pathATlib = "";
$O__logNotes = "";
$O__langOutput = "";
$O__URLpath = "";
$O__URLpathAlias = "";
$O__areas = array();

/**********
Includes
**********/
include($O__libPath . "/functions/server/O__dataRead.php");
include($O__libPath . "/functions/server/O__dataWrite.php");
include($O__libPath . "/functions/server/O__dirToArray.php");
include($O__libPath . "/functions/server/O__pageResponse.php");
include($O__libPath . "/functions/server/O__sanitize.php");
include($O__libPath . "/functions/server/O__sysMsg.php");
include($O__libPath . "/functions/server/O__xCrypt.php");
include($O__libPath . "/functions/server/O__XMLdata.php");
include($O__libPath . "/functions/server/O__XMLgetData.php");
include($O__libPath . "/pageTypes/O__logs/libraries/O__logger.php");

/**********
Define startup functions
**********/

/* Function: Check the session */
function O__sessionCheck(){
	global $O__DBpath,$O__cookieExpire,$O__cookiePath;
	session_save_path($O__DBpath . "/pageTypes/O__users/data/sessions/");
	if(!isset($_COOKIE["PHPSESSID"])){ $_COOKIE["PHPSESSID"] = 0; } // set default cookie name, if never been set
	setcookie(session_name(), $_COOKIE[session_name()], time()+$O__cookieExpire, $O__cookiePath); // Set cookie
	session_start();
	if(!isset($_SESSION["O__loggedIn"])){ $_SESSION["O__loggedIn"] = 0; } // set default O__loggedIn value, if never been set
}

/* Function: Set the user ID */
function O__userIDset(){
	global $O__userID;
	$O__userID = $_SESSION["O__userID"];
}

/* Function: Sign the log */
function O__signLogStart(){
	global $O__userID,$O__logNotes;
	O__logger("access",$_SERVER["REQUEST_URI"],"Request",$O__userID,$O__logNotes);	
}


/* Function: Check if URL gets redirected to HTTPS */
function O__redirectSecure(){
	global $O__DBpath, $O__signLog, $O__userID;
	
	//if(isset($_SERVER["HTTPS"]) && ($_SERVER["HTTPS"] != "on")) {
	if(!isset($_SERVER["HTTPS"])){
		// Setup
		$O__URLpath = strtolower(O__sanitize($_SERVER["REQUEST_URI"]));
		$O__URLfull = strtolower($_SERVER["HTTP_HOST"]) . $O__URLpath;
			
		if ($O__signLog == 1){ O__logger("access",$_SERVER["REQUEST_URI"],"Redirecting",$O__userID,"Secure redirect from '" . $O__URLfull . "'."); }
		header("Location: https://" . $O__URLfull);			
		exit;
	}
}

/* Function: Maintenance mode checker */
function O__maintModeCheck(){
	global $O__DBpath,$O__userID,$O__503exempt;
	
	
	// Settings: Load
	$O__fileData = O__XMLdata($O__DBpath . "/system/maintenance.xml", 0, 0);
	$O__active = O__XMLgetData($O__fileData,"/settings/setting[@id='active']/value");
	$O__exemptUsers = O__XMLgetData($O__fileData,"/settings/setting[@id='exemptUsers']/value");
	$O__redirectURL = O__XMLgetData($O__fileData,"/settings/setting[@id='redirectURL']/value");
	unset($O__fileData);
	
	// If update mode on
	if ($O__active == 1){
		 
		$O__exemptUsers = explode(",", trim($O__exemptUsers));
		$O__userExempt = 0;
		
		// Check for exempt users
		for($i=0; $i<count($O__exemptUsers); $i++){
			if($O__userID == $O__exemptUsers[$i]){
				$O__userExempt = 1;
				break;
			}
		}
		
		// Redirect user if user is not exempt AND current page does not match defined updateMode page
		//if (($O__userExempt == 0)&&($_SERVER["REQUEST_URI"] != "/" . $O__updateModePT)){
		if ($O__userExempt == 0){
			O__pageResponse("503");
		}
		
	}
}


/* Function: Check the URL for any needed redirects */
function O__redirectChecker(){
	global $O__DBpath, $O__signLog, $O__userID;
	
	// Setup
	$O__URLpath = strtolower(O__sanitize($_SERVER["REQUEST_URI"]));
	$O__URLfull = strtolower($_SERVER["HTTP_HOST"]) . $O__URLpath;
	$O__fileData = O__XMLdata($O__DBpath . "/pageTypes/O__redirects/data/redirects.xml", 0, 0);
	
	// Check redirect list for a match against current URL	
	for ($i=0; $i<count($O__fileData); $i++){
		$O__redirectState = (int)$O__fileData->redirect[$i]->state;
		$O__redirectFrom = strtolower((string)$O__fileData->redirect[$i]->from);
		$O__redirectCode = (int)$O__fileData->redirect[$i]->code;
		
		switch($O__redirectState){
				
			case "1": // partial match on URL path
				if (strpos($O__URLpath, $O__redirectFrom) !== false){
					$O__redirectTo = $O__fileData->redirect[$i]->to;
				}			

				break;
				
			case "2": // partial match on full URL 
				if (strpos($O__URLfull, $O__redirectFrom) !== false){
					$O__redirectTo = $O__fileData->redirect[$i]->to;
				}			

				break;
				
			case "3": // exact match on URL path
				if ($O__URLpath == $O__redirectFrom){
					$O__redirectTo = $O__fileData->redirect[$i]->to;
				}			

				break;
				
			case "4": // exact match on full URL
				if ($O__URLfull == $O__redirectFrom){
					$O__redirectTo = $O__fileData->redirect[$i]->to;
				}			

				break;
		}
		
		// If there's a redirect match
		if (isset($O__redirectTo)){		
			//echo($O__redirectState . " " . $O__URLfull . " --- From: " . $O__redirectFrom . " --- To: " . $O__redirectTo); exit;
			if ($O__signLog == 1){ O__logger("access",$_SERVER["REQUEST_URI"],"Redirecting",$O__userID,"Redirecting from '" . $O__redirectFrom . "' to '" . $O__redirectTo . "' with code '" . $O__redirectCode . "'."); }
			header("Location: " . $O__redirectTo,TRUE,$O__redirectCode);			
			exit;
		}
		
	}

}


/* Function: Check the URL for any needed aliases */
function O__aliasChecker(){
	global $O__DBpath,$O__URLpathAlias;
	
	// Setup
	$O__URLpath = strtolower(O__sanitize($_SERVER["REQUEST_URI"])); //get URL path
	$O__URLpath = strtok($_SERVER["REQUEST_URI"],"?"); //remove query
	$O__fileData = O__XMLdata($O__DBpath . "/pageTypes/O__aliases/data/aliases.xml", 0, 0);
	
	// Check redirect list for a match against current URL	
	for ($i=0; $i<count($O__fileData); $i++){
		//$O__aliasFrom = strtolower((string)$O__fileData->alias[$i]->from);
		$O__aliasFrom = (string)$O__fileData->alias[$i]->from;

		if ($O__URLpath == $O__aliasFrom){
		//if (strpos($O__URLpath, $O__aliasFrom) !== false){
			$O__URLpathAlias = $O__fileData->alias[$i]->to;
		}
		
	}

}

/* Function: Parse the URL */
function O__URLget(){
	global $O__URLpath,$O__URLpathAlias,$O__PTATinputs;
	
	if ($O__URLpathAlias != ""){
		// If an aliased URL
		$O__URLpath = $O__URLpathAlias;
	} else {
		// Grab URL and remove query
		$O__URLpath = strtok($_SERVER["REQUEST_URI"],"?");
	}
	$O__URLpath = ltrim($O__URLpath, "/");
	$O__URLpath = explode("/", $O__URLpath);
	
	// Get query string values & santize each
	parse_str($_SERVER["QUERY_STRING"],$O__PTATinputs);
	foreach($O__PTATinputs as $O__PTATinputKey => $O__PTATinputValue) {
		$O__PTATinputs[$O__PTATinputKey] = O__sanitize($O__PTATinputValue);
	}
}

/* Function: Setup language information */
function O__langSetup(){
	global $O__langOutput,$O__lang,$O__xmlns,$O__xmlLang;
	if ($O__lang != ""){ $O__langOutput = " lang=\"" . $O__lang . "\"";}
	if ($O__xmlns != ""){ $O__langOutput = " xmlns=\"" . $O__xmlns . "\"" . $O__langOutput . " xml:lang=\"" . $O__xmlLang . "\""; }
	
}

/* Function: Setup PageType and ActionType */
function O__PTATsetup(){
	global $O__DBpath,$O__libPath,$O__URLpath,$O__PT,$O__AT,$O__signLog,$O__userID,$O__logNotes;
	
	$O__PTs = O__dirToArray($O__libPath . "/pageTypes");
	
	// Get the PageType by cycling through whitelist array
	for ($i=0; $i<count($O__PTs); $i++){
		if ($O__URLpath[0] == $O__PTs[$i][0]){
			$O__PT = $O__PTs[$i][0];
			break;		
		}
	}

	// If not accessing whitelisted PageType
	if ($O__PT == ""){
		if ($O__signLog == 1){ O__logger("access",$_SERVER["REQUEST_URI"],"Not Found",$O__userID,$O__logNotes); }
		O__pageResponse("404");
	}
	
	// Get available ActionTypes
	$O__fileData = O__XMLdata($O__libPath . "/pageTypes/" . $O__PT . "/info.xml", 0, 0);
	$O__AT = $O__fileData->actions->default;
	$O__ATs = explode("," , $O__fileData->actions->all);
	
	// If an explicit ActionType is requested, check to see if it matches available ones
	if(isset($O__URLpath[2])){
		for ($i=0; $i<count($O__ATs); $i++){
			if ($O__URLpath[2] == $O__ATs[$i]){
				$O__AT = $O__ATs[$i];
				break;		
			}
		}
	}
}

/* Function: Check if user has permission to access PageType or ActionType */
function O__checkAccess(){
	global $O__DBpath, $O__usersDataPath, $O__PT, $O__AT, $O__userID, $O__signLog, $O__logNotes;
	
	$O__fileData = O__XMLdata($O__usersDataPath . "users/" . O__xCrypt($O__userID,"e") . ".xml", 0, 0);
	$O__userGroups = explode(",", trim($O__fileData->groups));
	unset($O__fileData);	
	
	// Load user and user's groups permisions
	for($i=0;$i<count($O__userGroups);$i++){
		$O__groupPath = $O__usersDataPath . "groups/" . strtolower($O__userGroups[$i]) . ".xml";	
		$O__PTcount = 0;
		$O__PTpermission = 0;
		$O__ATpermission = 0;
		
		if (file_exists($O__groupPath)){ // If user group exists
			$O__fileData = O__XMLdata($O__groupPath, 0, 0);

			// Check PageType Permission
			foreach($O__fileData->permissions->pageType as $PTpermissions) {
				if ($PTpermissions->name == $O__PT) { $O__PTpermission = 1; break; }
				$O__PTcount++;
			}
			
			// Check ActionType Permission
			if ($O__PTpermission == 1){ // if PageType permission found
				$O__ATpermissions = $O__fileData->permissions->pageType[$O__PTcount]->actions;
				$O__actionPermissions = explode("," , $O__ATpermissions);					
				foreach($O__actionPermissions as $O__action){
					$O__action = trim($O__action);
					if ($O__action == $O__AT) { $O__ATpermission = 1; break; }
				}
			}
		}
		
		if (($O__PTpermission == 1)&&($O__ATpermission == 1)){
			break; // Permission found.  Stop looking through granted permissions.
		}
	
	}
	
	// If after looking, no permissions found, show 403 page to user		
	if (($O__PTpermission == 0)||($O__ATpermission == 0)){
		if ($O__signLog == 1){ O__logger("access",$_SERVER["REQUEST_URI"],"Access Denied",$O__userID,$O__logNotes); }
		O__pageResponse("403");
	}
}

/* Function: Check if PageType has a header to include */
function O__PTheader(){
	global $O__libPath,$O__PT;
	
	$O__headerFilePath = $O__libPath . "/pageTypes/" . $O__PT . "/header.php";
	if (file_exists($O__headerFilePath)){ include($O__headerFilePath); }
}

/* Function: Load the needed page map */
function O__pageMap(){
	global $O__DBpath,$O__libPath,$O__PT,$O__AT,$O__layout,$O__theme,$O__pathPThead,$O__pathATlib,$O__areas,$O__ATcontainerTag,$O__ATcontainerAttributes;
	
	// Load PageType settings
	$O__fileData = O__XMLdata($O__DBpath . "/pageTypes/" . $O__PT . "/configs/pageMaps.xml", 0, 0);
	
	// Set the PageType head
	$O__pathPThead = $O__DBpath . "/pageTypes/" . $O__PT . "/heads/shared.php";

	// Set the ActionType path
	$O__pathATlib = $O__libPath . "/pageTypes/" . $O__PT . "/". $O__AT . ".php";
	
	// Get ActionType values
	$O__ATdata = O__XMLgetData($O__fileData,"/pageMaps/action[@type='" . $O__AT . "']");
	
	// Set layout and theme
	if(trim($O__ATdata->layout) != ""){ $O__layout = $O__ATdata->layout; } else { $O__layout = $O__fileData->defaults->layout; }
	if(trim($O__ATdata->theme) != ""){ $O__theme = $O__ATdata->theme; } else { $O__theme = $O__fileData->defaults->theme; }
	
	// Set the ActionType container tag and attributes
	if(trim($O__ATdata->container->tag) != ""){
		$O__ATcontainerTag = trim($O__ATdata->container->tag);
		$O__ATcontainerAttributes = trim($O__ATdata->container->attributes);		
	}
	
	// Set the default area container tags and attributes
	for($i=0; $i < count($O__ATdata->area); $i++){
		
		// Set default area container path		
		if ($O__ATdata[0]->area[$i]->contentPath == "shared"){
			$O__pathAreaRoot = $O__DBpath . "/shared/areas"; 
		} else { 
			$O__pathAreaRoot = $O__DBpath . "/pageTypes/" . $O__PT . "/areas";
		}
		
		// Assemble into array
		$O__areas[trim($O__ATdata->area[$i]["name"])] = 
			array(
				"defaultTag" => trim($O__ATdata->area[$i]->tag),
				"defaultAttributes" => trim($O__ATdata->area[$i]->attributes),
				"defaultPath" => $O__pathAreaRoot . "/" . trim($O__ATdata->area[$i]->file),
				"children" => array()
			);
		
		// Set the children area container tags and attributes
		for($j=0; $j < count($O__ATdata->area[$i]->child); $j++){
		
			// Set area path		
			if ($O__ATdata[0]->area[$i]->child[$j]->contentPath == "shared"){
				$O__pathAreaRoot = $O__DBpath . "/shared/areas"; 
			} else { 
				$O__pathAreaRoot = $O__DBpath . "/pageTypes/" . $O__PT . "/areas";
			}
			
			$O__areas[trim($O__ATdata->area[$i]["name"])]["children"][$j] =
				array(
					"childTag" => trim($O__ATdata->area[$i]->child[$j]->tag),
					"childAttributes" => trim($O__ATdata->area[$i]->child[$j]->attributes),
					"childPath" => $O__pathAreaRoot . "/" . trim($O__ATdata->area[$i]->child[$j]->file)
				);
		}
	}

}

/* Function: Write content into divs */
function O__writeAreas(){
	global $O__areas,$O__ATcontainerTag,$O__ATcontainerAttributes;
	
	// ActionType container: Opening tag and attributes
	if($O__ATcontainerTag != "") { 
		echo("<" . $O__ATcontainerTag); 
			if($O__ATcontainerAttributes != "") { echo(" " . $O__ATcontainerAttributes); }// attributes
		echo(">");			
	}
	
	// Default area
	foreach($O__areas as $O__areaName => $O__areaContents) {
					
		// Opening tag and attributes
		echo("<" . $O__areaContents["defaultTag"]);
			if($O__areaContents["defaultAttributes"] != "") { echo(" " . $O__areaContents["defaultAttributes"]); }// attributes
		echo(">");
		
		// Content
		if (count($O__areaContents["children"]) > 0){ // if there are children, load each of them
			for($i=0;$i<count($O__areaContents["children"]);$i++){
				// Child: Opening tag and attributes
				echo("<" . $O__areaContents["children"][$i]["childTag"]);
					if($O__areaContents["children"][$i]["childAttributes"] != "") { echo(" " . $O__areaContents["children"][$i]["childAttributes"]); }// attributes
				echo(">");
				
				// Child: Contents
				if (file_exists($O__areaContents["children"][$i]["childPath"])){ include($O__areaContents["children"][$i]["childPath"]); }
				
				// Child: Closing tag
				echo("</" . $O__areaContents["children"][$i]["childTag"] . ">\n");
			}			
		} else { // otherwise, load the default area content
			if (file_exists($O__areaContents["defaultPath"])){ include($O__areaContents["defaultPath"]); }
		}
				
		// Closing tag
		echo("</" . $O__areaContents["defaultTag"] . ">\n");
	}

	// ActionType container: Closing tag
	if($O__ATcontainerTag != "") { 
		echo("</" . $O__ATcontainerTag . ">\n");			
	}

}
/**********
Run startup functions
**********/
if ($O__useSessions == 1){ O__sessionCheck(); } 
if (isset($_SESSION["O__userID"])){ O__userIDset(); }
if ($O__signLog == 1){ O__signLogStart(); }
if ($O__redirectSecureForce == 1){ O__redirectSecure(); }
O__maintModeCheck();
if ($O__redirectCheck == 1){ O__redirectChecker(); }
if ($O__aliasCheck == 1){ O__aliasChecker(); }
O__URLget();
O__langSetup();
O__PTATsetup();
O__checkAccess();
O__PTheader();
O__pageMap();
?>
