<?php
/**
 * @class UserMgr
 * @version $Id: UserMgr.php 2926 2015-06-01 14:01:53Z elena $
 * 
 */

/*
define('DATAPATH', USERPATH.'WS/');
define('REQPATH',USERPATH.'REQ/');
define('RESDIRNAME',USERPATH.'RES/');
define('TTPATH', USERPATH.'TT/');
define('JOBPATH', USERPATH.'jobs/');
*/

class UserMgr 
{
	public $user, $IP, $userdir;
	protected $passwd;
	protected $sessionID;
	protected $userDirs = array('USERWSDIR' => 'WS', 'USERREQDIR' => 'REQ', 'USERDATADIR' => 'DATA',
					'USERWORKINGDIR' =>'RES', 'USERTTDIR' => 'TT', 'USERJOBDIR' => 'JOBS',
					'USERTEMPDIR' => 'TEMP');	
	protected $userGrps;
	protected $userGrpsCheckSum; //use to know if there is a modification in user groups
	protected $amdaClient; //client to dd webservice
	protected $paramMgr, $baseExtXml;
	protected $datasetsTimeRestriction;
	protected $datasetsTimeRestrictionCheckSum;
	
	public $isFirst = false;
	public $isOldWS = false;
	public $isNewInfo = false;
	public $isSpecialInfo = null;
	public $isGuest = false;

	function __construct($username = NULL, $password = NULL, $sessionID = NULL) 
	{	 
      // if magic quotes is on, stripslashes
		if(get_magic_quotes_gpc()) {
			$in = array(&$_GET, &$_POST, &$_COOKIE);
			while(list($k,$v) = each($in)) {
				foreach($v as $key => $val) {
					if(!is_array($val)) {
						$in[$k][$key] = stripslashes($val);
						continue;
					}
					$in[] =& $in[$k][$key];
				}
			}
			unset($in);
		}
     
		if (isset($_POST['username'])) {
			// Process Guest Login
			if (strcasecmp(trim($_POST['username']),"guest") == 0) {
				$this->processGuestLogin();
				$this->isGuest = true;
			}
			else {
				$this->user = trim($_POST['username']);
			}
		}
		else if (isset($username))
			$this->user = trim($username);

		if (!isset($this->passwd)) {
			if (isset($_POST['password'])) 
					$this->passwd = $_POST['password'];
			else if (isset($password))
					$this->passwd = $password;
		}

		if (isset($_GET['sessionID'])) 
			$this->user = $_GET['sessionID'];
		else if (isset($sessionID))
			$this->user = $sessionID;
		//TODO if AmdaClient is needed ?
		$this->amdaClient = new AmdaClient();
	}

	//TODO if needed?? set session ID
	protected function setID() {}

	public  function getIPclient()
	{
		/*
			REMOTE_ADDR is the only really reliable information,
			as it is transmitted to you by your web server that
			is handling the request. It can be theoretically 
			falsified as well, but that is much, much harder 
			than spoofing a header value, and an entirely different class of attack.
		*/
		if (getenv('REMOTE_ADDR'))  
		{       
			$realIP = getenv('REMOTE_ADDR'); 
			
			if ($realIP == '10.10.131.1' || $realIP == '10.10.135.119') { // proxy amdatest et openam; amdadev
				$allIPs = explode(',',$_SERVER['HTTP_X_FORWARDED_FOR']);
				$realIP = count($allIPs) > 1 ? trim($allIPs[0]) : $_SERVER['HTTP_X_FORWARDED_FOR'];
			}
		}          
		else 
		{
			//get local IP
			$command="hostname -i";
			$realIP = exec($command);
		}
		return $realIP;
	}
      
	public function getUserInfo()
	{
	// 	array("success"     => TRUE,
	// 		       "login"       => $login,
	// 		       "name"        => ($theUser->length > 0) ? $theUser->item(0)->getAttribute("name") : "undefined",
	// 		       "first_name"  => ($theUser->length > 0) ? $theUser->item(0)->getAttribute("first_name") : "undefined",
	// 		       "group"       => $this->getUserMemberGroups($login),
	// 		       "email"       => ($theUser->length > 0) ? $theUser->item(0)->getAttribute("email") : "undefined",
	// 		       "date"        => ($theUser->length > 0) ? $theUser->item(0)->getAttribute("date")  : "undefined",
	// 		       "news"        => ($theUser->length > 0) ? $theUser->item(0)->getAttribute("news")  : "0");
		$info =  $this->amdaClient->getUserInfo($this->user);
		$wsSize = intval($this->getWsSize()/1024./1024.);
		$quota = intval($this->getSpecialSettings()/1024./1024.);
		$info['total'] = $quota;
		$info['available'] = $quota - $wsSize;
		$info['used'] = $wsSize;
		
		return $info;
	}

	public function createDir() 
	{ 
		if (!mkdir($this->userdir, 0755, true)) return false;

		foreach ($this->userDirs as $key => $val) {
			if (!mkdir($this->userdir.$val.'/', 0755, true)) return false;
		}
		return true;
	}
	
	protected function loadUserGrps() 
	{
		if (isset($this->userGrps)) {
			return;
		}
		$info = $this->amdaClient->getUserInfo($this->user); 

		$this->userGrpsCheckSum = '';
		if (!empty($info['group'])) {
			$this->userGrpsCheckSum = md5($info['group']);
			$this->userGrps = explode(',',$info['group']);
		}
	}

	protected function loadDatasetsTimeRestriction()
	{
		if (isset($this->datasetsTimeRestriction)) {
			return;
		}
		$restrictionFilePath = datasetsTimeRestrictionJson;
		if (file_exists($restrictionFilePath)) {
			// Re-use the cache file if it's not older than 3600s.
			if (abs(time() - filemtime($restrictionFilePath)) < 3600) {
				$fileContent = file_get_contents($restrictionFilePath);
				if (!empty($fileContent)) {
					$this->datasetsTimeRestriction = json_decode($fileContent, TRUE);
					if (isset($this->datasetsTimeRestriction) && ($this->datasetsTimeRestriction !== FALSE)) {
						$this->datasetsTimeRestrictionCheckSum = md5($fileContent);
						return;
					}
				}
			}
		}

		$this->datasetsTimeRestrictionCheckSum = '';
		$this->datasetsTimeRestriction = $this->amdaClient->getDatasetsWithTimeRestriction();

		if ($this->datasetsTimeRestriction !== FALSE) {
			foreach ($this->datasetsTimeRestriction as &$datasetTimeRestriction) {
				$timeRestriction = $datasetTimeRestriction['restriction'];
				//Parse time restriction
				$n = sscanf($timeRestriction, "%04d-%02d-%02d", $yy, $mm, $dd);
				if ($n != 3) {
					$n = sscanf($timeRestriction, "%d", $ndays);
					if ($n != 1) {
						//Cannot parse the time restriction
						$timeRestriction = '';
					}
					else {
						$timeRestriction = date("Y-m-d", strtotime("-$ndays days"))."T23:59:59.999Z";
					}
				}
				else {
					$timeRestriction .= "T23:59:59.999Z";
				}
				$datasetTimeRestriction['restriction'] = $timeRestriction;
			}
			$content = json_encode($this->datasetsTimeRestriction);
			$this->datasetsTimeRestrictionCheckSum = md5($content);
			file_put_contents($restrictionFilePath, $content);
		}
	}

	/*
	* Check if special groups with settings exist and user is from these groups
	* Take the first group from user list
	*/
	protected function isSpecialGroup() 
	{
		if (!isset($this->userGrps))
			return NULL;

		$specialGrps = new DomDocument("1.0");

		if (!($specialGrps->load(specialGrpsXml))) return null; 

		$specialGrpNode = null;

		foreach ($this->userGrps as $grp) {
			$specialGrpNode = $specialGrps->getElementById($grp); 
			if ($specialGrpNode) break;                            
		}
		
		return $specialGrpNode;
	}
  
	public function getSpecialSettings()
	{
		$userSettings = new DomDocument("1.0");

		if (!file_exists(specialSettingsXml) || !$userSettings->load(specialSettingsXml)) {
			return DISK_QUOTA_standard;    
		}
		
		$theUser = $userSettings->getElementById($this->user);
		if (!$theUser) {
			return  DISK_QUOTA_standard;
		}
		
		$settings = $theUser->getElementsByTagName("setting");        
		if ($settings->length == 0) {
			return DISK_QUOTA_standard;
		}
		
		foreach ($settings as $setting) {                            
			if ($setting->getAttribute("name") == 'DISK_QUOTA')
				return $setting->getAttribute("value");                   
		}	 
		
	}
	
	public function setSpecialSettings() 
	{	
		$userSettings = new DomDocument("1.0");

		if (!file_exists(specialSettingsXml) || !$userSettings->load(specialSettingsXml)) {
			define("DISK_QUOTA", DISK_QUOTA_standard);    
			return; 
		}

		$theUser = $userSettings->getElementById($this->user);
		if (!$theUser) {
			define("DISK_QUOTA", DISK_QUOTA_standard);
			return;
		}
		$settings = $theUser->getElementsByTagName("setting");        
		if ($settings->length == 0) {
			define("DISK_QUOTA", DISK_QUOTA_standard);
			return;
		}

		foreach ($settings as $setting) {                            
			$key = $setting->getAttribute("name");
			$value =  $setting->getAttribute("value");
			$isSetting = $setting->hasAttribute("isSetting");                   
			if ($isSetting) {
				ini_set("$key",$value);
				}
			else {
				// Attention !!!  CONSTANT cannot be redefined
				define("$key",$value);                    
			}           
		} 		
	}

	/*
	*  make remote data tree from list of distant bases if it doezn't exist$center->monitor()
	*/ 
	protected function makeRemoteTree() 
	{  
	// unlink(USERWSDIR.'RemoteParams.xml');
		$this->paramMgr = new RemoteParamManager();
		$init_res = $this->paramMgr->init();
  
		$this->baseExtXml = new DomDocument("1.0");

		if ($init_res['success']) { // USERWSDIR.'RemoteParams.xml' exists
			// check/change access rights
			$basesWS = $this->paramMgr->xmlDom->getElementsByTagName('dataCenter');  // RemoteParams.xml
			$delete = new UserDeleteObsolete();
			
			$basesWsId = array();
			$basesToAdd = array();
			
			if ($basesWS->length > 0) {
	
				foreach ($basesWS  as $base) {
					$basesWsId[] = $base->getAttribute('xml:id'); 
				}
				
				foreach ($this->paramMgr->Bases as $baseNew) {
					if (!in_array($baseNew, $basesWsId)) {
						$basesToAdd[] = $baseNew;
					}
				}
				
				foreach ($basesWS  as $base) 
				{
					$baseId = $base->getAttribute('xml:id');
					$lastModif = $base->getAttribute('lastModif');
					if (!empty($lastModif)) {
						$lastModif = intval($lastModif);
						if (($lastModif > 0) && ((time() - $lastModif) < REMOTE_PARAMS_UPDATE_DELAY)) {
							continue;
						} 
					}
					if (!$this->baseExtXml->load(RemoteData.$baseId.'/base.xml')) 
					{ 
						$base->setAttribute("desc","ATTENTION!!! This DataCenter DOES NOT EXIST ANY MORE!!! Remove it from your tree");                                                                         
						$base->setAttribute('obsolete', true);
						
						error_log('NO '.RemoteData.$baseId.'/base.xml',1,email);	
						continue;
					}
					
					if ($base->hasAttribute('addable')) {
						$base->setAttribute('lastModif', time());
					  //   keep this base tree 
					  //	 error_log($baseId,1,email);
					}
					else {
						// totally rewrite
						if ($base->hasAttribute('isSimulation')) {
							$centerNode = $this->makeSimulationBase($baseId);
							$center = new $baseId();
							$centerNode->setAttribute('available', $center->monitor());
						}
						else {
							$center = new $baseId();
							if (method_exists($center, 'makeCenterNode'))
								$centerNode = $center->makeCenterNode($this->paramMgr->xmlDom);
							else { 
								// keep this base tree 
								error_log("Attention : $baseId has no makeCenterNode method", 1, email);
								continue;
							}
							$centerNode->setAttribute('available', TRUE);
						}
						
						$centerNode->setAttribute('name', $base->getAttribute('name'));
						$centerNode->setAttribute('desc', $base->getAttribute('desc'));
						$centerNode->setAttribute('lastModif', time());
						
						
						$base->parentNode->removeChild($base);
						
						$this->paramMgr->xmlDom->documentElement->appendChild($centerNode);
					}

					if ($baseId !== "FMI_GUMICS") {
						// Update Info on External Data Sets in RemoteTree.xml  
						$dataSets = $base->getElementsByTagName("dataset");
						if ($dataSets->length > 0) {
							foreach ($dataSets as $dataSet) {
								$dataSetID = $dataSet->getAttribute("xml:id");
								$origDataSet = $this->baseExtXml->getElementById($dataSetID);
								if ($origDataSet != null) {
									$desc = $origDataSet->getAttribute("desc");
									if ($desc != null) $dataSet->setAttribute("desc", $desc);
								}
								else {                                        
									$delete->setVI($dataSet->getAttribute('name'));                               
									$res = $delete->deleteDerived();                                                                           
									$res = $delete->deleteConditions();                                      
									$res = $delete->deleteRequests();                                                                               
									$res = $delete->deleteAliases();                                                                                                              
									$dataSet->setAttribute("desc","ATTENTION!!! This data set DOES NOT EXIST ANY MORE !!! Remove it from your tree");                    
									$dataSet->setAttribute('obsolete', true);
								}
							}
						}                
					}
				}
				
				// New Bases to add
				if (count($basesToAdd) > 0) {
					foreach ($basesToAdd as $baseToAdd) { 
						$centerNode = $this->makeNewBase($baseToAdd);  
                        if (isset($centerNode))
                            $this->paramMgr->xmlDom->documentElement->appendChild($centerNode);
					}
				}
				
				return $this->paramMgr->xmlDom->save($this->paramMgr->xmlName); 
			}
		}
      else if ($init_res['err'] == "RemoteParams file error") { // new RemoteParams.xml
      
			$this->paramMgr->xmlDom->formatOutput = true;
			$this->paramMgr->xmlDom->preserveWhiteSpace = false;

			$BASE = $this->paramMgr->xmlDom->createElement('dataRoot'); 
			$BASE->setAttribute('xml:id','myRemoteData-treeRootNode');

			foreach ($this->paramMgr->Bases as $baseId) 
			{    
				$centerNode = $this->makeNewBase($baseId);
				if (isset($centerNode))
					$BASE->appendChild($centerNode);  
			} 

			$this->paramMgr->xmlDom->appendChild($BASE);

			return $this->paramMgr->xmlDom->save($this->paramMgr->xmlName);
	   }
	}
	
	protected function makeNewBase($baseId)
	{
	// no data base description ; skip this data base  
		if (!@file_exists(RemoteData.$baseId.'/base.xml')) return NULL;

		// can't read base.xml ; skip this data base
		if (!@$this->baseExtXml->load(RemoteData.$baseId.'/base.xml')) return NULL;

		$base = $this->paramMgr->basesDom->getElementById($baseId);
		
		if ($base->hasAttribute('default'))  
		{ 
			if ($base->hasAttribute('isSimulation')) {
					$centerNode = $this->makeSimulationBase($baseId);
					$center = new $baseId();
					$centerNode->setAttribute('available',$center->monitor());
			}
			/*
			*   Some small & well known data centers are included by default: 
			*   Each VI structure and VI (dataset) description at DDBASE for them should exist
			*/
			else 
			{
				$center = new $baseId();				
				$centerNode = $center->makeCenterNode($this->paramMgr->xmlDom);
				$centerNode->setAttribute('available', TRUE);
			}
			
			$centerNode->setAttribute('name', $base->getAttribute('name'));
			$centerNode->setAttribute('desc', $base->getAttribute('desc'));
			
			if ($base->hasAttribute('addable')) {
				$centerNode->setAttribute('addable', TRUE);
			}
		}
		else 
		{
			$centerNode = $this->paramMgr->xmlDom->importNode($base, true);
			$centerNode->setAttribute('available', TRUE);
		}

      return $centerNode;
	}
	
	protected function makeSimulationBase($baseId)
	{
		$centerNode = $this->paramMgr->xmlDom->importNode($this->baseExtXml->getElementById($baseId), true);
		$datasets = $centerNode->getElementsByTagName('dataset');
		foreach ($datasets as $dataset)
		{
			$infoFileName = $this->paramMgr->getInfoName($dataset->getAttribute('name'));
			$this->paramMgr->localInfo = RemoteData.$baseId.'/'.$infoFileName;

			if (!@file_exists($this->paramMgr->localInfo)) continue;				 

			$params = $dataset->getElementsByTagName('parameter');
			$this->paramMgr->remoteViId = $dataset->getAttribute('name');
			foreach ($params as $param) 
			{
				$this->paramMgr->paramId = $param->getAttribute('name');
				$paramGlobalId =  $param->getAttribute('xml:id');				  
				$this->paramMgr->paramXML = RemoteData.'PARAMS/'.$paramGlobalId.'.xml';	
							
				if (!@file_exists($this->paramMgr->paramXML)) continue;
				if (!$this->paramMgr->paramDom) 
						$this->paramMgr->paramDom = new DomDocument("1.0");

				$this->paramMgr->paramDom->load($this->paramMgr->paramXML);
				
				if (!$this->paramMgr->makeComponents($param)) continue;
			}
		}
		return $centerNode;
	}
	
	
	protected function processGuestLogin() 
	{
// 		if (!$this->check_email_address($_POST['password'])) 
// 		{
// 			die('<a href="index.html"><h3>Invalid e-mail address. Please, try once more.</h3></a>');
// 		}
		
//		$passwd = $_POST['password'];
        $passwd = "public";
		$IP = $this->getIPclient();
		$Guest = new Guest($IP,$passwd);
		// email and IP in guests.login
		$Guest->registerGuest();
		$Guest->checkGuestTimes();
		$user = $Guest->addGuest(); 

		if ($user == "allGuestLoginsInUse") 
		{
			die('<a href="index.html"><h3>Sorry, all guest accounts are currently in use. Please, try to login in 30 min.</h3></a>');  
		}
		
		$this->user = $user;
		$this->passwd = "guest";
	}    
 
/*****************************************************************
*                           PUBLIC FUNCTIONS
*****************************************************************/

	public function setPath() 
	{
		if (isset($_GET['sessionID'])) {
			$this->user = $_GET['sessionID'];
			$this->userdir = USERPATH."/".$this->user."/";                
		}
		else if (isset($this->user)) {
			$this->userdir = USERPATH."/".$this->user."/";
		}

		$usrdir = $this->userdir;

		define ("USERDIR", "$usrdir/");

		foreach ($this->userDirs as $key => $val) {
			$dir = $usrdir.$val;
			define("$key","$dir/");
		} 
	}

	public function ddCheckUser() 
	{
		$this->IP = $this->getIPclient();
		$cmdCheckUser =  "DDCheckUser ".$this->IP." ".$this->user." 1> /dev/null 2> /dev/null";   
		system($cmdCheckUser, $res);
		return $res;
	}
  
	public function ddLogin() 
	{
		$this->IP = $this->getIPclient();

		$loginCommd = "DDHtmlLogin ".$this->user." ".$this->passwd." ".$this->IP;
		system($loginCommd, $res);

		return $res;
	}
    
          	  	
	public function init() 
	{ 
		if ($this->ddLogin() != 0) {
			return FALSE;
		} 
            
		$this->userdir = USERPATH."/".$this->user."/";

		if (!is_dir($this->userdir)) {           
			if (!$this->createDir()) { 
				die("Login for ".$this->user." failed: Can't create WS dirs");
			}
			$this->isFirst = true;
		}

		$requestManager = new RequestManagerClass();
		try {
			$res = $requestManager->runIHMRequest($this->user, $this->getIPclient(), FunctionTypeEnumClass::USERWSINIT, array());
		} catch (Exception $e) {
			die("Login for ".$this->user." failed: Error in WS dirs - ".$e->getMessage());
		}

		if (file_exists($this->userdir.'newLogin')) {
			touch($this->userdir.'lastLogin', filemtime($this->userdir.'newLogin'));
		}
		else {
			touch($this->userdir.'lastLogin', time() - 5*86400); // last 5 days
		}
		
		// if new info exists it will be shown to : 
		// public => to all
		// special => to group members
		if (file_exists($this->userdir.'newInfo')) {                
			$amdaInfo = new AmdaNews($this->user);
			$info = $this->getUserInfo($this->user);
			$status = $amdaInfo->makeInfo($info['group']); 

			if ($status) $this->isNewInfo = true; 
			unlink($this->userdir.'newInfo');
		}
		touch($this->userdir.'newLogin');          

		$this->setPath(); 		
	
		if (!$this->makeLocalTree())
				die("Login for ".$this->user." failed: Can't make LocalParams.xml");;
		
		$ok = $this->makeRemoteTree();	                      		

		/*if (!file_exists(USERWSDIR.'Request.xml')) $reqMgr = new RequestMgr();
		if (!file_exists(USERWSDIR.'Tt.xml')) $ttMgr = new TimeTableMgr();
		if (!file_exists(USERWSDIR.'Alias.xml')) $ttMgr = new AliasMgr();*/

		//TODO sessionID = user + WSname
		$sessionID = $this->user;
		
		/*
		* Special settings are defined in the generic_data/SpecialSettings/Settings.xml
		*/
		$this->setSpecialSettings(); 
		
		/*
		* Special groups are defined in the generic_data/SpecialSettings/Groups.xml
		*/
		if (isset($this->userGrps)) {
		//	$specialGroup = $this->isSpecialGroup();
			$specialGroup = false;
			// Special Info for special groups
			if ($specialGroup) {
				// Special Settings for special groups - first visit just copying
				if ($this->isFirst) {
					$grp = $specialGroup->getAttribute('xml:id');
					$tags = $specialGroup->getElementsByTagName('folder');

					foreach ($tags as $tag) {                 
						$folder = $tag->getAttribute('name');
						
						foreach (glob(SpecialSettingsDir.$grp."/".$folder."/*") as $file) {
							copy($file, $this->userdir.$folder."/".basename($file));
						} 
					}
					// mark to show help information
					touch($this->userdir."$grp"."Help");
				}
				// add requests
				else { }
				$grpName = $specialGroup->getAttribute('xml:id');
				$helpName = "$grpName"."Help";
	
				if (file_exists(HELPPATH.$helpName) && file_exists($this->userdir.$helpName))
								$this->isSpecialInfo = $helpName;
			}
		}
		return $sessionID;
	}

	protected function makeLocalTree()
	{
		$this->loadDatasetsTimeRestriction();

		$this->loadUserGrps();

		if (file_exists(USERWSDIR.'LocalParams.xml')) {
			if (file_exists(USERWSDIR.'userGrpsChecksum') && file_exists(USERWSDIR.'datasetsTimeRestrictionCheckSum')) {
				$lastGrpsChecksum = file_get_contents(USERWSDIR.'userGrpsChecksum');
				$lastDatasetsTimeRestrictionCheckSum = file_get_contents(USERWSDIR.'datasetsTimeRestrictionCheckSum');
				if (($lastGrpsChecksum == $this->userGrpsCheckSum) && ($lastDatasetsTimeRestrictionCheckSum == $this->datasetsTimeRestrictionCheckSum)) {
					//No modification in groups for this user
					if (filemtime(USERWSDIR.'LocalParams.xml') == filemtime(LocalData.'/LocalParams.xml')) {
						//And no modification in LocalParams file => skip makeLocalTree
						return true;
					}
				}
			}
			unlink(USERWSDIR.'LocalParams.xml');
		}

		if (!copy(LocalData.'/LocalParams.xml', USERWSDIR.'LocalParams.xml'))
				die("Login for ".$this->user." failed: Can't copy LocalParams.xml");
		//Save groups checksum used to generate this user local tree
		file_put_contents(USERWSDIR.'userGrpsChecksum', $this->userGrpsCheckSum);
		//Save datasets time restrictions used to generate this user local tree
		file_put_contents(USERWSDIR.'datasetsTimeRestrictionCheckSum', $this->datasetsTimeRestrictionCheckSum);
				
		$result = $this->updateTreeForGrpsAndTimeRestrictions(USERWSDIR.'LocalParams.xml');

		//Set modif time to the original one
		touch(USERWSDIR.'LocalParams.xml', filemtime(LocalData.'/LocalParams.xml'));

		return TRUE;
	}
	
	protected function updateTreeForGrpsAndTimeRestrictions($file)
	{
		$xml = new DomDocument("1.0");
		
		if(!$xml->load($file)) 
			die("Login for ".$this->user." failed: Can't load LocalParams.xml");
		
		$xp = new domxpath($xml);                                                                             
	  
		if (!empty($this->userGrps)) {
			foreach ($this->userGrps as $grp) {
				$nodes = $xp->query("//*[@group='".$grp."']");
			
				if ($nodes->length > 0)
					foreach ($nodes as $node) {
							$node->removeAttribute('group');
							if ($node->hasAttribute('restriction')) {
								if ($node->getAttribute('restriction') != "plotOnly") {
									$node->removeAttribute('restriction');
								}
							}
					}
			}
		}

		if (!empty($this->datasetsTimeRestriction)) {
			foreach ($this->datasetsTimeRestriction as $datasetTimeRestriction) {
				$dataset_id = str_replace('_','-',$datasetTimeRestriction['vi']);
				$nodes = $xp->query("//dataset[@xml:id='".$dataset_id."' or @PriorID='".$dataset_id."']");
				if ($nodes->length > 0) {
					foreach ($nodes as $node) {
						$timeRestriction = $datasetTimeRestriction['restriction'];
						if (!empty($timeRestriction)) {
							$node->setAttribute('timeRestriction', $timeRestriction);
						}
					}
				}
			}
		}
		
		return $xml->save($file);
	}
	
	public function dirSize($dir, $files_to_delete = array()) 
	{
		$handle = opendir($dir);

		$mas = 0;
		while ($file = readdir($handle)) {
			if ($file != '..' && $file != '.' && !is_dir($dir.'/'.$file)) {
				if (in_array($file, $files_to_delete)) {
					unlink($dir.'/'.$file);
					continue;
				}
				$mas += filesize($dir.'/'.$file);
			} 
			else if (is_dir($dir.'/'.$file) && $file != '..' && $file != '.') {
				$mas += $this->dirSize($dir.'/'.$file, $files_to_delete);
			}
		}
		return $mas;
	} 

	public function  getWsSize($delete_log_files = FALSE) 
	{
		$dirsToCheck = array(USERDATADIR, USERTTDIR, USERWORKINGDIR);
		$wsSize = 0;
		if ($delete_log_files) {
			$files_to_delete = array(
				'example.log',
				'cmd_output',
			);
		}
		else {
			$files_to_delete = array();
		}
		foreach ($dirsToCheck as $dir) 
			if (is_dir($dir)) $wsSize += $this->dirSize($dir, $files_to_delete);

		return $wsSize;
	}
	
    // http://www.ilovejackdaniels.com/php/email-address-validation/ 
	public function check_email_address($email) 
	{
		// First, we check that there's one @ symbol, and that the lengths are right
		 if (!preg_match("/^[^@]{1,64}@[^@]{1,255}$/", $email)) 
		{
		// Email invalid because wrong number of characters in one section, or wrong number of @ symbols.
			return false;
		}
		
		// Split it into sections to make life easier
		$email_array = explode("@", $email);
		$local_array = explode(".", $email_array[0]);
		for ($i = 0; $i < sizeof($local_array); $i++) 
		{
			 if (!preg_match("@^(([A-Za-z0-9!#$%&'*+/=?^_`{|}~-][A-Za-z0-9!#$%&'*+/=?^_`{|}~\.-]{0,63})|(\"[^(\\|\")]{0,62}\"))$@", $local_array[$i])) {
				return false;
			}
		}

		if (!preg_match("/^\[?[0-9\.]+\]?$/", $email_array[1])) { // Check if domain is IP. If not, it should be valid domain name
			$domain_array = explode(".", $email_array[1]);
			if (sizeof($domain_array) < 2) {
				return false; // Not enough parts to domain
			}
			for ($i = 0; $i < sizeof($domain_array); $i++) 
			{
				if (!preg_match("/^(([A-Za-z0-9][A-Za-z0-9-]{0,61}[A-Za-z0-9])|([A-Za-z0-9]+))$/", $domain_array[$i])) {
					return false;
				}
			}
		}
		return true;
	}         
}
?>