<?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 $userMissions;
     protected $amdaClient; //client to dd webservice
     
     public $isFirst = false;
     public $isNewInfo = false;
     public $isSpecialInfo = null;

      function __construct($username,$password,$sessionID) {
 	 
      // 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();
              }
              else {
                $this->user = trim($_POST['username']);
               }
        }
	else if (isset($username))
	  $this->user = trim($username);

        //TODO crypt / decrypt
        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;
        $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');      
            }          
            else {
                        //get local IP
                     $command="hostname -i";
                     $realIP = exec($command);
            }
          return $realIP;
      }

      
      public function getUserInfo()
      {
      	 return $this->amdaClient->getUserInfo($this->user);
      }

/*
*          Get Available Missions for a User (groups restriction)
*/   
     protected function getAvailableMissionsByUser()
     {
       $res  = $this->amdaClient->getUserAvailableMissions($this->user);

       if (!$res['success'])
         return array('local' => array(), 'external' => array());
       return array('local' => $res['local'], 'external' => $res['external']);
     }

    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;
    }

/*
* Check if special groups with settings exist and user is from these groups
* Take the first group from user list
*/
    protected function isSpecialGroup() {
         
        $specialGrps = new DomDocument("1.0");
 
        if (!($specialGrps->load(specialGrpsXml)))
                 return null; 

        $info = $this->amdaClient->getUserInfo($this->user); 
 
        $userGrps = explode(',',$info['group']);

         $specialGrpNode = null;

         foreach ($userGrps as $grp) {
            $specialGrpNode = $specialGrps->getElementById($grp); 
            if ($specialGrpNode) break;                            
          }
 
         return $specialGrpNode;
    }
        
/*
*  Totally replace IMPEX staff in user remote tree
*/
    protected function updateImpex()
    {
        $myRemoteBases = new DomDocument("1.0");   
                    
        if (!$myRemoteBases->load(USERWSDIR.'RemoteParams.xml')) 
                                                        return false;

        $myBases = $myRemoteBases->getElementsByTagName('dataCenter');


        if ($myBases->length < 1) 
                            return false;
        // Delete all impex staff at first
        $i = $myBases->length - 1; 
 
        while ($i > -1) { 
            $base = $myBases->item($i);
            $id = $base->getAttribute('xml:id'); 

            if ($id == 'FMI_GUMICS'){
              $simuRemoteBases = new DomDocument("1.0"); 
              $simuRemoteBases->load(USERWSDIR.'RemoteParams.xml');
            
	      $gumicsNode = $simuRemoteBases->getElementById('FMI_GUMICS');
              if ($gumicsNode != NULL)
 		$gumicsRuns = $gumicsNode->getElementsByTagName('runID');
            }
            
            
 
	    if (($base->hasAttribute('isSimulation')) || $id == "CLWeb") { 
                                    $base->parentNode->removeChild($base);   
                }                  
            $i--; 
        } 

        $remoteBases = new DomDocument("1.0");
        if (!$remoteBases->load(RemoteData.'Bases.xml'))
                                    return false;
        $bases = $remoteBases->getElementsByTagName('dataCenter');
         
        if ($bases->length < 1)
                            return false;   

        $myRootElement = $myRemoteBases->documentElement; 

        // and add impex
       foreach ($bases as $base) {
                //TODO && $id != 'FMI_GUMICS' or ! hasAttribute('isAddable')
                if ($base->hasAttribute('group') && 
                    $base->getAttribute('group') == 'IMPEX') {
                                                
                        $baseId = $base->getAttribute('xml:id');
                        $baseXml = new DomDocument("1.0");
                        // no data base description ; skip this data base  
                        if (!file_exists(RemoteData.$baseId.'/base.xml')) continue;
 
                        // can't read base.xml ; skip this data base
                        if (!$baseXml->load(RemoteData.$baseId.'/base.xml'))  continue;                                                          
                                                                                                                                
                        $myBase = $myRemoteBases->importNode($baseXml->getElementById($baseId), true);
                        $myBase->setAttribute('name', $base->getAttribute('name'));
                        $myBase->setAttribute('desc', $base->getAttribute('desc'));
                        
                        if ($baseId == "FMI_GUMICS"){
			    $gumicsSimuReg = $myRemoteBases->getElementById('FMI_GUMICS_Earth_Magnetosphere');
			                     
			    if (($gumicsSimuReg != NULL)&& ($gumicsRuns->length > 0)){ 
			      for($c = 0; $c < $gumicsRuns->length; $c++){
				$node = $gumicsRuns->item($c);
				$node = $myRemoteBases->importNode($node, true);
				$gumicsSimuReg->appendChild($node); 
			      } 
			    }
                        }
                        
                        
                        $myRootElement->appendChild($myBase); 
                }
           }  
                   
       return $myRemoteBases->save(USERWSDIR.'RemoteParams.xml');

    } 

 /*
 *  make local data tree from list of missions
 */   
    protected function makeLocalTree() 
    {
            if (file_exists(DATAPATH.'rank.json')) 
                $cmpArr = json_decode(file_get_contents(DATAPATH.'rank.json'), true);
            else 
                $cmpArr = null;

            $localMissions = new DomDocument("1.0");
	    $localMissions->load(LocalData.'Missions.xml');
 
            $xp = new domxpath($localMissions);
            $bases = $xp->query("//MissionID[@status='required']");
                           
            $piBase = new DomDocument("1.0");
            $piBase->formatOutput = true;
            $piBase->preserveWhiteSpace = false;
            
            $localDom  = new DomDocument("1.0");
            $BASE = $localDom->createElement('dataRoot'); 
            $Amda = $localDom->createElement('dataCenter');
            $Amda_name = new DomAttr('name', 'AMDA');
            $Amda->appendChild($Amda_name);
            $Amda_desc = new DomAttr('desc', 'AMDA_Internal_Data_Base');
            $Amda->appendChild($Amda_desc);
 
            $availableMis = $this->userMissions['local'];
 
            foreach ($bases as $base) {            
                     $xml = LocalData.'DD_'.$base->nodeValue.'.xml';
                     $notAvailable = (array_search($base->nodeValue,$availableMis) === FALSE);
                     if (file_exists($xml)){
                        if (!$piBase->load($xml))
                                error_log($base->nodeValue,1,email);     
                        $vi = $piBase->getElementsByTagName("mission");
                        if ($vi->length > 0) for ($i = 0; $i < $vi->length; $i++){
                              $nodeNew = $localDom->importNode($vi->item($i),true);
                              $nodeNew->setAttribute('available',!$notAvailable);
                              // set rank by target name if file rank.json exists
                             if (is_array($cmpArr)) {
                                $targets = $vi->item($i)->getElementsByTagName('target');
                                if ($targets->length > 0) {
                                    // First target is the main one
                                    $target = $targets->item(0);
                                    $index = $cmpArr[$target->nodeValue];
                                    if ($index)  
                                            $nodeNew->setAttribute('rank',$index);
                                    else $nodeNew->setAttribute('rank', 999);
                                  }
                                 }
                            $Amda->appendChild($nodeNew);
                         }                  
                    }
              }
           
             if ($Amda->hasChildNodes()) $BASE->appendChild($Amda);             
             $localDom->appendChild($BASE);
             
            // set access rights at all levels 
            $xpLoc = new domxpath($localDom);
            // get all nodes with 'group' attribute (restricted)
            $restrictedTags =  $xpLoc->query("//*[@group]");

            if ($restrictedTags->length > 0) {
                    $info = $this->amdaClient->getUserInfo($this->user);              
                    $userGrps = explode(',',preg_replace('/\s+/', '',$info['group']));

                    foreach ($restrictedTags as $restriction) {
                        $group = $restriction->getAttribute('group');
                        $available = in_array($group,$userGrps);
                        // special restrictions
                        if (!$available && $restriction->getAttribute('restriction')) {
                                $restriction_type = $restriction->getAttribute('restriction');
                                // time restriction
                                if ($restriction_type == 'time') {
                                    $id_restr = $restriction->getAttribute('xml:id');
                                    $restrictions = $this->amdaClient->getTimeRestriction(str_replace(":","_",$id_restr));
                                    if ($restrictions) {
                                        $restriction->setAttribute('restricted', $restrictions['days']);
                                        $dataStop = $restriction->getElementsByTagName('dataStop');
                                        if ($dataStop->length > 0) {
                                            $globalStop = explode("T", $restrictions['globalstop']);
                                            $dataStop->item(0)->nodeValue  = str_replace("-", "/", $globalStop[0]);
                                        }
                                    }
                                }
                                // absolute restriction: remove node
                                else {
                                    $restriction->parentNode->removeChild($restriction);
                                }
                         } 
                         else {
                            // general restriction: disable node
                            $restriction->setAttribute('restricted', !$available);
                        }
                    }
            }

            $xsl = new DomDocument("1.0");
            $xsl->load(XMLPATH.'dd2tree.xsl');
            
            $xslt = new XSLTProcessor();
            $xslt->importStylesheet($xsl);
             
            $piBase->loadXML($xslt->transformToXML($localDom));
             
            $piBase->save(USERWSDIR.'LocalParams.xml');
      }
  
/*
 *  make remote data tree from list of distant bases if it doezn't exist
 */   
      protected function makeRemoteTree() {
   
        $remoteBases = new DomDocument("1.0");
        $availableMis = $this->userMissions['external'];
 
        if (file_exists(USERWSDIR.'RemoteParams.xml')) 
        {
            // replace IMPEX nodes
            $status = $this->updateImpex();
            if (!$status) error_log('IMPEX Remote Base can not be updated',1,email);
            // check/change access rights
            $remoteBases->load(USERWSDIR.'RemoteParams.xml');
            $bases = $remoteBases->getElementsByTagName('dataCenter');
            $delete = new UserDeleteObsolete();
            if ($bases->length > 0) 
                foreach ($bases as $base) {
                    $baseId = $base->getAttribute('xml:id');
                    $notAvailable = (array_search($baseId,$availableMis) === FALSE);
                    $base->setAttribute('available',!$notAvailable);
                        
                    if ($base->getAttribute('isSimulation')) continue;
                        
                    // Update Info on External Data Sets in UserTree.xml for everything except IMPEX
                    $dataSets = $base->getElementsByTagName("dataset");
                    if ($dataSets->length > 0) {
                        $baseExtDom = new DomDocument("1.0");
                        if (!$baseExtDom->load(RemoteData.$baseId.'/base.xml')) { 
                            $base->setAttribute("desc","ATTENTION!!! This Base set DOES NOT ANY MORE EXIST!!! Remove it from your tree");                                                                         
                            $base->setAttribute('obsolete', true);
                            error_log('NO '.RemoteData.$baseId.'/base.xml',1,email);
                            continue;
                        }
                        foreach ($dataSets as $dataSet) {
                            $dataSetID = $dataSet->getAttribute("xml:id");
                            $origDataSet = $baseExtDom->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 ANY MORE EXIST!!! Remove it from your tree");                    
                                    $dataSet->setAttribute('obsolete', true);
                            }
                        }
                    }                  
            } 
                                                                                                                                                                                                                        
            return $remoteBases->save(USERWSDIR.'RemoteParams.xml'); 
        }	 
             
	    $remoteBases->load(RemoteData.'Bases.xml');
            $bases = $remoteBases->getElementsByTagName('dataCenter');
               
            if ($bases->length == 0) return 'NO REMOTE BASES';         
  	   
	    $paramMgr = new ParamMgr();
	    $paramMgr->xmlDom = new DomDocument("1.0");
	    $paramMgr->xmlDom->formatOutput = true;
	    $paramMgr->xmlDom->preserveWhiteSpace = false;
            
 
            $BASE = $paramMgr->xmlDom->createElement('dataRoot'); 
	    $BASE->setAttribute('xml:id','myRemoteData-treeRootNode');
  
	    $baseXml = new DomDocument("1.0");
	    	    
	    foreach ($bases as $base) {
	     
	      $toInclude = $base->hasAttribute('default'); 
	      $baseId = $base->getAttribute('xml:id');
	      $paramMgr->baseId = $baseId;
	      
	      $notAvailable = (array_search($baseId,$availableMis) === FALSE);
 
                // no data base description ; skip this data base  
 	       if (!file_exists(RemoteData.$baseId.'/base.xml')) continue;
	  	                                    	       
                // can't read base.xml ; skip this data base
                if (!$baseXml->load(RemoteData.$baseId.'/base.xml')) continue;			        			      

            //        Some small & well known data centers are included by default: 
            //        Each VI structure and VI (dataset) description at DD Server for them should exist
	      if ($toInclude)  { 	           
 
	 	    $center = $paramMgr->xmlDom->importNode($baseXml->getElementById($baseId), true);
		    $datasets = $center->getElementsByTagName('dataset');

		    foreach ($datasets as $dataset){
                            // THEMIS => pseudo remote center; everything is predefined
			  if ($baseId === 'THEMIS') {
				$params = $dataset->getElementsByTagName('parameter'); 
				foreach ($params as $param)  
						$paramMgr->makeThemisComponents($param);
			    } 
			  else {
				$infoFileName = $paramMgr->getInfoName($dataset->getAttribute('name'));
				$paramMgr->localInfo = RemoteData.$baseId.'/'.$infoFileName;

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

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

				      $paramMgr->paramDom->load($paramMgr->paramXML);
				      
				      if (!$paramMgr->makeComponents($param)) continue;
				}
			  }			  
		    }
	       }
	     else {
		$center = $paramMgr->xmlDom->importNode($base, true);
	      }

	    $center->setAttribute('name', $base->getAttribute('name'));
	    $center->setAttribute('desc', $base->getAttribute('desc'));
	    $center->setAttribute('available',!$notAvailable);
	    $BASE->appendChild($center); 
 
           }  
            $paramMgr->xmlDom->appendChild($BASE);
         
            return $paramMgr->xmlDom->save(USERWSDIR.'RemoteParams.xml');
	     
      }

    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'];
        $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
*****************************************************************/
    // migration from old to new AMDA
     public function convertWS() {

        $convert = new UserWsTransfer($this->user); 

       $res =  $convert->checkWS();
       if (!$res['success']) return $res;

       $res =  $convert->transferDerived();
       $msg = $res['msg'];

       $res = $convert->transferTimeTables();
       $msg .= $res['msg'];

       $res = $convert->transferConditions();
       $msg .= $res['msg'];

       $res = $convert->transferRequests();
       $msg .= $res['msg'];

       $res =  $convert->transferMyData(); 
       $msg .= $res['msg'];

       error_log('Transfer workspace from old AMDA for '.$this->user, 1, 'amda@irap.omp.eu');
       return array('success' => true, 'msg' => $msg);     
    }

     public function setPath() {

        if (isset($_GET['sessionID'])) {
                $this->user = $_GET['sessionID'];
                $this->userdir = USERPATH."/".$this->user."/";                
        }
            // for testing purposes
           else if (defined('TRANSFERUSER')) {
                  $this->userdir = BASE_PATH."test/".TRANSFERUSER."/";
        }
        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 =  DDBIN."DDCheckUser ".$this->IP." ".$this->user." 1> /dev/null 2> /dev/null";   
		system($cmdCheckUser, $res);
		return $res;
          }
  
      public function ddLogin() {

             $this->IP = $this->getIPclient();

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

	    return $res;
	  }
    
          	  	
      public function init() { 
      
            if ($this->ddLogin() != 0) 
                        die('<h2>You are trying to log in as '.$this->user.'<br/> Please check that you entered a valid password</h2>');
            
            $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;                
            }

            if (file_exists($this->userdir.'newLogin')) {
                copy($this->userdir.'newLogin',$this->userdir.'lastLogin');
                $dt = filemtime($this->userdir.'newLogin');
                touch($this->userdir.'lastLogin', $dt);
            }
            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);
             // if status = 0 - it is special info to group members only
             // else to all  
                $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(); 
            
            $this->userMissions = $this->getAvailableMissionsByUser();

            if (!file_exists(USERWSDIR.'LocalParams.xml'))
            	symlink(DATAPATH.'/LocalParams.xml', USERWSDIR.'LocalParams.xml');
            //$this->makeLocalTree();
	 
	    $ok = $this->makeRemoteTree();
	                      
	    if (!file_exists(USERWORKINGDIR.'DD_Request.res'))
			      copy(Plot.'DD_Request.res',USERWORKINGDIR.'DD_Request.res');

            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 groups are defined in the generoc_data/SpecialSettings/Groups.xml
            */
            $specialGroup = $this->isSpecialGroup();
            
           // 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;
      }

        public function dirSize($dir) {

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


        public function  getWsSize() {

            $dirsToCheck = array(USERDATADIR, USERTTDIR, USERWORKINGDIR);
            $wsSize = 0;
            foreach ($dirsToCheck as $dir) 
                if (is_dir($dir)) $wsSize += $this->dirSize($dir);

            return $wsSize;
        }
 
        public function check_email_address($email) {
        //http://www.ilovejackdaniels.com/php/email-address-validation/

                // First, we check that there's one @ symbol, and that the lengths are right
                if (!ereg("^[^@]{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 (!ereg("^(([A-Za-z0-9!#$%&'*+/=?^_`{|}~-][A-Za-z0-9!#$%&'*+/=?^_`{|}~\.-]{0,63})|(\"[^(\\|\")]{0,62}\"))$", $local_array[$i])) {
                        return false;
                    }
                }

                if (!ereg("^\[?[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 (!ereg("^(([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;
            }

          
 }

?>