<?php
 
 /** 
  * Klasse UserAuth
  * Methodensammlung rund um Registrierung und Login von Usern
  * (Password-verifizierung und -erstellung, Pruefung der Email-Adresse)
  *************************************************************************/
   
  
class UserAuthExceptions extends Exception{}
Class UserAuth{
	
	/**********************************************************************************************************
	*										Standard-Einstellungen der Klasse !
	*					Diese Einstellungen bearbeiten oder setzen ueber Methode setAttribute()
	***********************************************************************************************************/
	
	/***********************************************************
	*						Datenbank
	*
	*			Festlegen der Tabellen und Spaltennamen
	************************************************************/
	/** 
	* Tabellenname der Webbenutzertabelle
	* @var String
	* @access private
	*/
	private $usertab = 'wwwusers';
	
	/** 
	* Zellenname der BenutzerID
	* @var int
	* @access private
	*/
	private $celluserid = 'uid';
	
	/** 
	* Zellenname der Benutzernamen
	* @var String
	* @access private
	*/
	private $cellusername = 'uname';
	
	/** 
	* Zellenname der Email-Adressen
	* @var String
	* @access private
	*/
	private $cellemail = 'uemail';
	
	/** 
	* Zellenname der Passwoerter
	* @var String
	* @access private
	*/
	private $cellpassword = 'upass';
	
	/** 
	* Zellenname des Aktivierungsstatus
	* @var String
	* @access private
	*/
	private $cellactstat = 'uact';
	
	/** 
	* Zellenname des Reset/Aktivierungstokens
	* @var String
	* @access private
	*/
	private $celltoken = 'uactlink';
	
	/** 
	* Zellenname des Token-Ablaufdatus
	* @var String
	* @access private
	*/
	private $celltokenexpire = 'uactexpire';
	
	
	/** 
	* Tabellenname der Sessions fuer den Autologin
	* @var String
	* @access private
	*/
	private $sessiontab = 'session_hashes';
	
	/** 
	* Zellenname der UserID (Sessions)
	* @var String
	* @access private
	*/
	private $cellsessuserid = 'userid';
	
	/** 
	* Zellenname der Sessionhashes
	* @var String
	* @access private
	*/
	private $cellsesshash = 'sesshash';
	
	/** 
	* Zellenname des Ablaufdatum der Session
	* @var String
	* @access private
	*/
	private $cellsessexpire = 'sessexpire';
	
	/** 
	* Zellenname des User_Agent Strings der Session
	* @var String
	* @access private
	*/
	private $cellsessuagent = 'useragent ';
	
	/***********************************************************
	*						Passwort
	*
	*			Festlegen des Passwort-Peppers
	************************************************************/
	
	/** 
	* Wert des Passwort-Peppers
	* @var String
	* @access private
	*/
	private $pepper = PEPPER;
	
	/***********************************************************
	*						Token und Hash
	*
	*			Festlegen der Standardwerte fuer die Token 
	*						und Hashgenerierung
	************************************************************/
	/** 
	* Zeitraum der Token-Gueltigkeit in Tagen
	* @var int
	* @access private
	*/
	private $tokenexpiredays = 10;
	
	/** 
	* Zeitraum der Reset-Token-Gueltigkeit in Stunden
	* @var int
	* @access private
	*/
	private $tokenresexpirehours = 1;
	
	/** 
	* Laenge des zu generierenden Tokens
	* @var int
	* @access private
	*/
	private $tokenlenght = 40;	
	
	/** 
	* Laenge des zu generierenden Hash-Wertes
	* @var int
	* @access private
	*/
	private $hashlength = 50;
	
	/***********************************************************
	*							Session
	*
	*			Festlegen der Session-Standardwerte
	************************************************************/
	/** 
	* Name der gesetzten Session
	* @var String
	* @access private
	*/
	private $sessionname = 'TestSessionName';	
	
	/** 
	* Gueltigkeitsdauer der Autologin-Session.
	* Y = Jahr, M = Monate, W = Wochen, D = Tage, S = Stunden, i = Minuten
	* Beispiel: gueltigkeit ein Jahr: '1Y'
	* @var String
	* @access private
	*/
	private $sesshashexpire = '1W'; 
	
	/***********************************************************
	*					Account-Aktivierungsmail
	*
	*				Festlegen der Standardeinstellungen fuer
	*						die Aktivierungsmail
	************************************************************/
	/** 
	* URL des Aktivierungslinks
	* Der Platzhalter [%token] wird durch den generierten Token ersetzt
	* @var String
	* @access private
	*/
	private $actmailurl = 'http//meine-fiktive-domain.de/index.php?t=[%token]';
	
	/** 
	* Betreffzeile der Aktivierungsmail
	* @var String
	* @access private
	*/
	private $actmailsubject = 'Aktiviere deine Registrierung';
	
	/** 
	* Dateipfad zum Email-Template der Aktivierungsmail
	* @var String
	* @access private
	*/
	private $actmailtemplate ='/templates/actmail.tpl';
	
	/** 
	* Alternativtext der Aktivierungsmail, wenn Client keine HTML-Mails darstellt
	* An der Stelle des Platzhalters [%acturl] wird der generierte Aktivierungslink eingesetzt
	* @var String
	* @access private
	*/
	private $altactmailtext =	'
									Vielen Dank fuer deine Registreirung.\N
									Bitte oeffne folgende URL in deinem Browser um deinen Account zu aktivieren:\N
									[%acturl]
								';
	
	/***********************************************************
	*						Passwort-Reset-Mail
	*
	*				Festlegen der Standardeinstellungen fuer
	*					die Passwort-Reset-Mail
	************************************************************/
	
	/** 
	* URL des Passwort-Reset-Links
	* Der Platzhalter [%token] wird durch den generierten Token ersetzt
	* @var String
	* @access private
	*/
	private $resmailurl ='http//meine-fiktive-domain.de/index.php?t=[%token]';
	
	/** 
	* Betreffzeile der Passwort-Reset-Mail
	* @var String
	* @access private
	*/
	private $resmailsubject = 'Zuruecksetzen des Passworts';
	
	/** 
	* Dateipfad zum Email-Template der Passwort-Reset-Mail
	* @var String
	* @access private
	*/
	private $resmailtemplate ='templates/resmail.tpl';
	
	/** 
	* Alternativtext der Passwort-Reset-Mail, wenn Client keine HTML-Mails darstellt
	* An der Stelle des Platzhalters [%resurl] wird der generierte Aktivierungslink eingesetzt
	* @var String
	* @access private
	*/
	private $altresmailtext =	'
									Um dein Passwort zurueckzusetzen, oeffne bitte folgenden Link: \n
									[%resurl]
								';
	
	/**********************************************************************************************************
	*									Arbeits- Eigenschaften der Klasse !
	*										Ab hier nichts veraendern.
	***********************************************************************************************************/
	
	/** 
	* Referenz zur PDO Klasse
	* @var ObjectReferenz
	* @access private
	*/
	private $db = NULL;
		
	/** 
	* Wert des Token-Strings
	* @var String
	* @access private
	*/
	private $token = '';
	
	/** 
	* Wert des Token-Hash fuer die DB
	* @var String
	* @access private
	*/
	private $dbtoken = '';
		
	/** 
	* Ablauf Datum und Uhrzeit des Tokens
	* @var string
	* @access private
	*/
	private $tokenexpiredatetime = NULL;
		
	/** 
	* Hash-Wert des RememberME-Cookies
	* @var String
	* @access private
	*/
	private $cookiesesshash = NULL;	
		
	/** 
	* Benutzer-Email-Adresse
	* @var String
	* @access private
	*/
	private $emailadress = NULL;
	
	/** 
	* BenutzerID
	* @var int
	* @access private
	*/
	private $userid = NULL;
	
	/** 
	* Benutzername
	* @var String
	* @access private
	*/
	private $username = NULL;
	
	/** 
	* Benutzer-Passwort
	* @var String
	* @access private
	*/
	private $password = NULL;	
	
	/**********************************************************************************************************
	*											METHODEN !
	***********************************************************************************************************/
	
	/*
	* Konstruktormethode uebernimmt die Referenz auf die PDO-Klasse
	* 
	* @param Ref $dbconnection Referenz auf das PDO Objekt
	*/
	public function __construct($dbconnection){
		$this -> db = $dbconnection;
		if(!isset($_SESSION)){
			session_name($this -> sessionname);
			session_start();
		}
		
		
	}
	
	/***********************************************************
	*						Setter-Methoden
	*
	*				Setzen der Arbeitseigenschaften
	************************************************************/
	
	/*
	* Methode zum setzen der Standard-Einstellungen
	* 
	* @param String_oder_Array $att Attributname - Array wenn mehrere Einstellungen veraendert werden sollen
	* 			- Wenn mehrer Einstellungen verändert werden sollen => array('Attributname' => 'Attributwert, ...)
	*			- (Atriibutname: siehe Methode switchandsetAttribute())
	* @param $value Wert des Attributs (nur wenn $att kein Array)
	*/
	public function setAttribute($att,$value=NULL){
		if(is_array($att)){
			$keys = array_keys($att);
			$count=0;
			$errorflag = 0;
			$errormessage = array();
			foreach($keys as $k){
				$setret = $this -> switchandsetAttribute($k,$att[$k]);
				if(is_string($setret)){
					$errormessage[] = $setret;
					$errorflag = 1;
				}				
			}
			if($errorflag == 1){
					$exceptionerror = implode(';',$errormessage);
					throw new UserAuthExceptions('Fehler beim setzen der Attribute.Meldungen:'.$exceptionerror);
			}else{
				return TRUE;
			}
		}elseif(is_string($att) && !empty($value)){
			$setret = $this -> switchandsetAttribute($att,$value);
				if(is_string($setret)){
					throw new UserAuthExceptions('Fehler beim setzen des Attributes.Meldung:'.$setret);					
				}elseif(is_bool($setret)){
					return TRUE;
				}
		}else{
			throw new UserAuthExceptions('Es muss ein array oder ein String plus Wert uebergeben werden. ($uath -> setAttribute($Attribute,$Value) oder $uath -> setAttribute($AttributeArray))');
		}
	}
	
	/*
	* Helper-Methode fuer setAttribute(). Auswaehlen der zu aendernden Eigenschaft
	* 
	* @param String $att Attributname
	* @param $value Wert des Attributs
	*/
	private function switchandsetAttribute($att,$value){
		$errorflag = 0;
		Switch($att){
			case 'UNameUserTable':
					if(is_string($value)){
						$this -> usertab = $value;
						
					}else{
						$errorflag = 1;
						$errormessage = '- Wert "UNameUserTable" muss ein String sein';
					}
					
					break;
			case 'UNameCellUserID':
					if(is_string($value)){
						$this -> celluserid = $value;
						
					}else{
						$errorflag = 1;
						$errormessage = '- Wert "UNameCellUserID" muss ein String sein';
					}
					break;
			case 'UNameCellUsername':
					if(is_string($value)){
						$this -> cellusername = $value;
					}else{
						$errorflag = 1;
						$errormessage = '- Wert "UNameCellUsername" muss ein String sein';
					}
					break;
			case 'UNameCellEmail':
					if(is_string($value)){
						$this -> cellemail = $value;
						
					}else{
						$errorflag = 1;
						$errormessage = '- Wert "UNameCellEmail" muss ein String sein';
					}
					break;
			case 'UNameCellPassword':
					if(is_string($value)){
						$this -> cellpassword = $value;
													
					}else{
						$errorflag = 1;
						$errormessage = '- Wert "UNameCellPassword" muss ein String sein';
					}
					break;
			case 'UNameCellActivationStatus':
					if(is_string($value)){
						$this -> cellactstat = $value;
													
					}else{
						$errorflag = 1;
						$errormessage = '- Wert "UNameCellActivationStatus" muss ein String sein';
					}
					break;
			case 'UNameCellToken':
					if(is_string($value)){
						$this -> celltoken = $value;
													
					}else{
						$errorflag = 1;
						$errormessage = '- Wert "UNameCellToken" muss ein String sein';
					}
					break;
			case 'UNameCellTokenExpire':
					if(is_string($value)){
						$this -> celltokenexpire = $value;
													
					}else{
						$errorflag = 1;
						$errormessage = '- Wert "UNameCellTokenExpire" muss ein String sein';
					}
					break;
			case 'SNameSessionTable':
					if(is_string($value)){
						$this -> sessiontab = $value;
													
					}else{
						$errorflag = 1;
						$errormessage = '- Wert "SNameSessionTable" muss ein String sein';
					}
					break;
			case 'SNameCellUserID':
					if(is_string($value)){
						$this -> cellsessuserid = $value;
													
					}else{
						$errorflag = 1;
						$errormessage = '- Wert "SNameCellUserID" muss ein String sein';
					}
					break;
			case 'SNameCellSessionHash':
					if(is_string($value)){
						$this -> cellsesshash = $value;
													
					}else{
						$errorflag = 1;
						$errormessage = '- Wert "SNameCellSessionHash" muss ein String sein';
					}
					break;
			case 'SNameCellSessExpire':
					if(is_string($value)){
						$this -> cellsessexpire = $value;
													
					}else{
						$errorflag = 1;
						$errormessage = '- Wert "SNameCellSessExpire" muss ein String sein';
					}
					break;
			case 'SNameCellUserAgent':
					if(is_string($value)){
						$this -> cellsessuagent = $value;
													
					}else{
						$errorflag = 1;
						$errormessage = '- Wert "SNameCellUserAgent" muss ein String sein';
					}
					break;
			case 'PasswordPepper':
					if(is_string($value)){
						$this -> pepper = $value;
													
					}else{
						$errorflag = 1;
						$errormessage = '- Wert "PasswordPepper" muss ein String sein';
					}
					break;
			case 'ActivationTokenExpireDays':
					if(is_integer($value)){
						$this -> tokenexpiredays = $value;
													
					}else{
						$errorflag = 1;
						$errormessage = '- Wert "ActivationTokenExpireDays" muss ein Integer sein';
					}
					break;
			case 'PwResetTokenExpireHours':					
					if(is_integer($value)){
						$this -> tokenresexpirehours = $value;
													
					}else{
						$errorflag = 1;
						$errormessage = '- Wert "PwResetTokenExpireHours" muss ein Integer sein';
					}
					break;
			case 'TokenLenght':
					if(is_integer($value)){
						$this -> tokenlenght = $value;
													
					}else{
						$errorflag = 1;
						$errormessage = '- Wert "TokenLenght" muss ein Integer sein';
					}
					break;
			case 'SessionHashLength':
					if(is_integer($value)){
						$this -> hashlength = $value;
													
					}else{
						$errorflag = 1;
						$errormessage = '- Wert "SessionHashLength" muss ein Integer sein';
					}
					break;
			case 'SessionCookieName':
					if(is_string($value)){
						$this -> sessionname = $value;
													
					}else{
						$errorflag = 1;
						$errormessage = '- Wert "SessionCookieName" muss ein String sein';
					}
					break;
			case 'SessionHashExpire':
					if(is_string($value)){
						$this -> sesshashexpire = $value;
													
					}else{
						$errorflag = 1;
						$errormessage = '- Wert "SessionHashExpire" muss ein String sein';
					}
					break;
			case 'ActivationMailURL':
					
					if(is_string($value)){
						$this -> actmailurl = $value;
													
					}else{
						$errorflag = 1;
						$errormessage = '- Wert "ActivationMailURL" muss ein String sein';
					}
					break;
			case 'ActivationMailSubject':
					
					if(is_string($value)){
						$this -> actmailsubject = $value;
													
					}else{
						$errorflag = 1;
						$errormessage = '- Wert "ActivationMailSubject" muss ein String sein';
					}
					break;
			case 'ActivationMailHTMLTemplate':
					
					if(is_string($value)){
						$this -> actmailtemplate = $value;
													
					}else{
						$errorflag = 1;
						$errormessage = '- Wert "ActivationMailHTMLTemplate" muss ein String sein';
					}
					break;
			case 'ActivationMailAlternateText':
					
					if(is_string($value)){
						$this -> altactmailtext = $value;
													
					}else{
						$errorflag = 1;
						$errormessage = '- Wert "ActivationMailAlternateText" muss ein String sein';
					}
					break;
			case 'PwResetMailURL':
					
					if(is_string($value)){
						$this -> resmailurl = $value;
													
					}else{
						$errorflag = 1;
						$errormessage = '- Wert "PwResetMailURL" muss ein String sein';
					}
					break;
			case 'PwResetMailSubject':
					
					if(is_string($value)){
						$this -> resmailsubject = $value;
													
					}else{
						$errorflag = 1;
						$errormessage = '- Wert "PwResetMailSubject" muss ein String sein';
					}
					break;
			case 'PwResetMailTemplate':
					
					if(is_string($value)){
						$this -> resmailtemplate = $value;
													
					}else{
						$errorflag = 1;
						$errormessage = '- Wert "PwResetMailTemplate" muss ein String sein';
					}
					break;
			case 'PwResetMailAlternateText':
					
					if(is_string($value)){
						$this -> altresmailtext = $value;
													
					}else{
						$errorflag = 1;
						$errormessage = '- Wert "PwResetMailAlternateText" muss ein String sein';
					}
					break;
					
			default:
							$errorflag = 1;
							$errormessage = '- "'.$att.'" ist keine gueltige Eigenschaft';
		}
		if($errorflag == 1){
			return $errormessage;			
		}else{
			return TRUE;
		}
	}
	/*
	* Setzen der BenutzerID
	* 
	* @param String $uname Benutzername
	*/
	private function setUserID(){
		if(!empty($this -> username) || !empty($this -> cellemail)){
			try{
				$dbquery = '
							SELECT 
								'.$this -> celluserid.' 
							FROM 
								'.$this -> usertab.' 
							WHERE 
								'.$this -> cellusername.' = ?
							OR 
								'.$this -> cellemail.' = ?
							';
				$dbstmt = $this -> db -> prepare($dbquery);			
				$dbstmt -> bindValue(1, $this -> username,PDO::PARAM_STR);			
				$dbstmt -> bindValue(2, $this -> emailadress,PDO::PARAM_STR);
				$dbstmt -> execute();
				if($result = $dbstmt -> fetchall()){
					$this -> userid = $result[0][$this -> celluserid];
					return TRUE;
				}else{
					return FALSE;
				}
			}
			catch (PDOException $e){
				$error = $e -> getMessage();				
				$trace = $e -> getTrace();
				$failquery = $trace[0]['args'][0];
				$line = $e -> getLine();
				throw new UserAuthExceptions('Fehler bei der Datenbankabfrage ! Fehler: "'.$error.'"; Zeile: "'.$line.'"; Query: "'.$failquery.'"');
			}	
		}else{
			throw new UserAuthExceptions('Fehlende Angabe des Benutzernames oder der Email-Adresse (setUsername oder setEmail ausfuehren)');
			
		}
	}
	
	/*
	* Setzen des Benutzernamens
	* 
	* @param String $uname Benutzername
	*/
	public function setUsername($uname){
		$this -> username = $uname;
	}
	
	/*
	* Setzen des Benutzer-Passwortes
	* 
	* @param String $pass Benutzer-Passwort
	*/
	public function setPassword($pass){
		$this -> password = $pass;
	}
	
	/*
	* Setzen der Benutzer-Email-Adresse
	* 
	* @param String $email Emailadresse
	*/
	public function setEmail($email){
		$this -> emailadress = $email;
	}
	
	/***********************************************************
	*					Registrier-Methoden
	*
	*		Methoden rund um die Registrierung neuer Benutzer
	************************************************************/
	
	/**
	* All-in-One Methode zur Registration von neuen Benutzern
	* @param array $dbvalues Array mit weiteren Eintragungen fuer die Benutzerdatenbank (Der Index ist der Zellenname, Der Wert ist der Wert der Zelle)
	* @return Bool TRUE bei erfolgreicher Registrierung.
	* @return array $errorRegister bei einem Fehler 
	*/
	public function doRegister($dbvalues = array()){
		if($this -> username == NULL || $this -> password == NULL || $this -> emailadress == NULL){
			if(empty($this -> password)){
				$statuspw = 'nicht gesetzt';
			}else{
				$statuspw = 'gesetzt';
			}
			throw new UserAuthExceptions('doRegister -> Die Eigenschaften Username,Password und Emailadress muessen gesetzt sein. Zustand zum Fehlerzeitpunkt: Username = "'.$this -> username.'"; Emailadresse = "'.$this -> emailadress.'"; Passwort = "'.$statuspw.'"');			
		}
		else{	
			$errorflag = 0;
			$errorRegister = array	(
										'usernametaken' => 0,
										'emailtaken' => 0,
										'emailinvalid' => 0
									);
			if(!$this -> checkUsername()){
				$errorflag = 1;				
				$errorRegister['usernametaken'] = 1;				
			}			
			$checkemail = $this -> checkEmailAdress();
			if($checkemail['EMailavilable'] == 0){
				$errorflag = 1;				
				$errorRegister['emailtaken'] = 1;				
			}
			if($checkemail['EMailcorrectly'] == 0){
				$errorflag = 1;				
				$errorRegister['emailinvalid'] = 1;	
				$errorRegister['emailtaken'] = 0;				
			}
			if ($errorflag == 0){
				$phash = $this -> createPasswordHash();
				$this -> generateActResToken();
				$keys = array_keys($dbvalues);
				$addtosqlqueryindex ='';
				foreach($keys as $index){
					$addtosqlqueryindex .= ','.$index;
				}
				$addtosqlqueryvalues ='';
				foreach($dbvalues as $values){
					$addtosqlqueryvalues .= ',?';
				}
				try{
					$dbquery = '
							INSERT INTO 
								'.$this -> usertab.'
								(
								'.$this -> cellusername.',
								'.$this -> cellpassword.',
								'.$this -> cellemail.',
								'.$this -> cellactstat.',
								'.$this -> celltoken.',
								'.$this -> celltokenexpire.'
								'.$addtosqlqueryindex.'
								)
							VALUES
								(
								?,
								?,
								?,
								"0",
								?,
								?'.
								$addtosqlqueryvalues.'
								)
							';
					$dbstmt = $this -> db -> prepare($dbquery);
					$dbstmt -> bindValue(1, $this -> username,PDO::PARAM_STR);
					$dbstmt -> bindValue(2, $phash,PDO::PARAM_STR);
					$dbstmt -> bindValue(3, $this -> emailadress,PDO::PARAM_STR);
					$dbstmt -> bindValue(4, $this -> dbtoken,PDO::PARAM_STR);
					$dbstmt -> bindValue(5, $this -> tokenexpiredatetime,PDO::PARAM_STR);
					$i = 6;
					foreach($dbvalues as $values){
						$dbstmt -> bindValue($i, $values,PDO::PARAM_STR);
						$i++;
					}								
					$dbstmt -> execute();
					
				}
				catch(PDOException $e){
					$error = $e -> getMessage();				
					$trace = $e -> getTrace();
					$failquery = $trace[0]['args'][0];
					$line = $e -> getLine();
					throw new UserAuthExceptions('Fehler bei der Datenbankabfrage ! Fehler: "'.$error.'"; Zeile: "'.$line.'"; Query: "'.$failquery.'"');
				}
				$this -> setUserID();
				$this -> sendActResLink();	
				$this -> password = NULL;
				return TRUE;
				
			}else{
				return $errorRegister;
			}
			
		}
	}
	
	/**
	* Methode zum Pruefen ob der Username bereits vergeben ist
	*
	* @return Bool Benutzername vergeben = False, Benutzername frei = TRUE
	*/
	public function checkUsername(){
		if(isset($this -> username)){
			try{
				$dbquery = '
							SELECT 
								* 
							FROM 
								'.$this -> usertab.' 
							WHERE 
								'.$this -> cellusername.' = ?
							';
				$dbstmt = $this -> db -> prepare($dbquery);			
				$dbstmt -> bindValue(1, $this -> username,PDO::PARAM_STR);			
				$dbstmt -> execute();
				if($result = $dbstmt -> fetchall()){
					return FALSE;
				}else{
					return TRUE;
				}
			}
			catch (PDOException $e){
				$error = $e -> getMessage();				
				$trace = $e -> getTrace();
				$failquery = $trace[0]['args'][0];
				$line = $e -> getLine();
				throw new UserAuthExceptions('Fehler bei der Datenbankabfrage ! Fehler: "'.$error.'"; Zeile: "'.$line.'"; Query: "'.$failquery.'"');
				
			}	
		}else{
			
			throw new UserAuthExceptions ('Zum Pruefen des Benutzernamens muss ein Benutzername gesetzt werden. Methode setUsername($username) benutzen');
			
		}
		
	}
   
   /**
	* Methode zum verifizieren der Email-Adresse 
	* mit anschliessender Pruefung ob diese in der DB schon vorhanden ist
	* 
	* @return Array mit Index "EMailcorrectly" und "Emailavailable".
	*/
	public function checkEmailAdress (){
		if(isset($this -> emailadress)){
			$emailstatus = 	[
							'EMailcorrectly' => 0,
							'EMailavilable' => 0,
							];
			if(filter_var($this -> emailadress, FILTER_VALIDATE_EMAIL)){
				$emailstatus['EMailcorrectly'] = 1;						
				try{				
					$dbquery = '
								SELECT 
									* 
								FROM 
									'.$this -> usertab.' 
								WHERE 
									'.$this -> cellemail.' = ?
								';
					$dbstmt = $this -> db -> prepare($dbquery);			
					$dbstmt -> bindValue(1, $this -> emailadress,PDO::PARAM_STR);			
					$dbstmt -> execute();
					if($result = $dbstmt -> fetchall()){
						$emailstatus['EMailavilable'] = 0;
					}else{
						$emailstatus['EMailavilable'] = 1;
					}
				}
				catch (PDOException $e){
					$error = $e -> getMessage();				
					$trace = $e -> getTrace();
					$failquery = $trace[0]['args'][0];
					$line = $e -> getLine();
					throw new UserAuthExceptions('Fehler bei der Datenbankabfrage ! Fehler: "'.$error.'"; Zeile: "'.$line.'"; Query: "'.$failquery.'"');
					
				}
			}else{
				$emailstatus['EMailcorrectly'] = 0;				
			}
			return $emailstatus;
			
			
		}else{
			
			throw new UserAuthExceptions ('Zum Pruefen der Email-Adresse muss eine Email-Adresse gesetzt werden. Methode setEmai($emailadresse) benutzen');
			
		}
	
	}
	
	/**
	* Methode zum erzeugen des Passworthashes nach Defaultverschluesselung des Webserver.
	* 
	* @return String erzeugter Passwort-Hash
	*/
	private function createPasswordHash(){
		if (isset($this -> password) && isset($this -> pepper)){			
			return password_hash($this -> password.$this -> pepper,PASSWORD_DEFAULT);
		}else{
			
			throw new UserAuthExceptions ('Zum erstellen eines Passwort-Hashes muss das Passwort und das Pepper gesetzt werden. Methode setPassword() benutzen und Pepper in den Standardeinstellungen anpassen');
			
		}
	}
	
	/**
	* Generiert einen gueltigen Aktivierungstoken und ueberprueft ob dieser Token bereits vorhanden ist
	* Wenn $renewacttoken = 1 wird der Aktivierungstoken eines vorhandenen Benutzers erneutet
	* @param Boolean $renewacttoken Aktivierungstoken erneuern
	* @param Boolean $ActorRes Waehlen des Tokentyps: 0 = Aktivierungstoken, 1 = Passwort-Reset-Token
	* @return Bool FALSE wenn angegebene Email-Adresse nicht in der DB existiert (nur bei renewacttoken)
	* @return array 'token' = generierter Aktivierungstoken im Klartext, 'dbtoken' = gehashter Aktivierungstoken mit ".act" Kennzeichnung fuer die Datenbank
	*/
	public function generateActResToken($ActorRes = 0,$renewacttoken = 0){
		$tokenavailable = 0;	
		$error = 0;		
		while($tokenavailable == 0){			
			$ftoken = $this -> generateToken();
			$fdbtoken = password_hash($ftoken,PASSWORD_DEFAULT);
			if($ActorRes == 1){
				$fdbtoken .= '.pwres';
			}else{
				$fdbtoken .= '.act';
			}
			try{				
				$dbquery = '
							SELECT 
								'.$this -> celltoken.'
							FROM 
								'.$this -> usertab.' 
							WHERE 
								'.$this -> celltoken.' = ?							
							';
				$dbstmt = $this -> db -> prepare($dbquery);	
				$dbstmt -> bindValue(1, $fdbtoken,PDO::PARAM_STR);				
				$dbstmt -> execute();
				if($result = $dbstmt -> fetchall()){
					$tokenavailable = 0;
				}else{
					$tokenavailable = 1;
				}
			}
			catch (PDOException $e){
				$error = $e -> getMessage();				
				$trace = $e -> getTrace();
				$failquery = $trace[0]['args'][0];
				$line = $e -> getLine();
				throw new UserAuthExceptions('Fehler bei der Datenbankabfrage ! Fehler: "'.$error.'"; Zeile: "'.$line.'"; Query: "'.$failquery.'"');
			}
			
		}
		if($tokenavailable == 1){
			if($renewacttoken == 1){		
				$date = new DateTime();
				$date->add(new DateInterval('P'.$this -> tokenexpiredays.'D'));
				$expiredate = $date->format('Y-m-d H:i:00');
				try{
					$dbquery = '
								UPDATE 
									'.$this -> usertab.' 
								SET 
									'.$this -> celltoken.' = ?, 
									'.$this -> cellactstat.' = "0",
									'.$this -> celltokenexpire.' = ?
								WHERE 
									'.$this -> cellemail.' = ?							
								';
					$dbstmt = $this -> db -> prepare($dbquery);				
					$dbstmt -> bindValue(1, $fdbtoken,PDO::PARAM_STR);
					$dbstmt -> bindValue(2, $expiredate,PDO::PARAM_STR);
					$dbstmt -> bindValue(3, $this -> emailadress,PDO::PARAM_STR);					
					$dbstmt -> execute();	
					unset($date);
					$countres = $dbstmt -> rowCount();
					if ($countres == 0){
						$error = 1;
					}
				}
				catch (PDOException $e){
					$error = $e -> getMessage();				
					$trace = $e -> getTrace();
					$failquery = $trace[0]['args'][0];
					$line = $e -> getLine();
					throw new UserAuthExceptions('Fehler bei der Datenbankabfrage ! Fehler: "'.$error.'"; Zeile: "'.$line.'"; Query: "'.$failquery.'"');
			}
			}
			if($error == 0){
				$date = new DateTime();
				if($ActorRes == 1){
					$date->add(new DateInterval('PT'.$this -> tokenresexpirehours.'H'));
				}else{
					$date->add(new DateInterval('P'.$this -> tokenexpiredays.'D'));
				}
				$expiredate = $date->format('Y-m-d H:i:00');
				$this -> token = $ftoken;
				$this -> dbtoken = $fdbtoken;
				$this -> tokenexpiredatetime = $expiredate;
				return array('token' => $ftoken,'dbtoken' => $fdbtoken, 'expiredatetime' => $expiredate);
				
			}else{
				return FALSE;
			}
		} 
		
		
	}
	/**
	* Methode zum versenden des Aktivierungslinks.
	* 
	* @return Bool TRUE bei erfolgreichem Versand, ansonsten FALSE/Exception
	*/
	public function sendActResLink($actorres = 0){
		if(isset($this -> emailadress)){									
				$actmail = new phpmailer;
				$actmail -> addAddress($this -> emailadress);
				$mtoken = base64_encode($this -> userid.'.'.$this -> token);
				if($actorres == 1){
					$actmail -> Subject = $this -> resmailsubject;
					$parseurl = str_replace('[%token]',$mtoken, $this -> resmailurl);
					$parse = file_get_contents($this ->resmailtemplate);
					$actmail -> AltBody = str_replace('[%resurl]',$parseurl,$this -> altresmailtext);
				}else{	
					$actmail -> Subject = $this -> actmailsubject;				
					$parseurl = str_replace('[%token]',$mtoken, $this -> actmailurl);
					$parse = file_get_contents($this ->actmailtemplate);
					$actmail -> AltBody = str_replace('[%acturl]',$parseurl,$this -> altactmailtext);
				}
				$bodytext = str_replace(array('[%username]','[%url]'), array($this -> username, $parseurl), $parse);						
				$actmail -> Body = $bodytext;
				try{
					$actmail -> send();
				}
				catch (phpmailerException $e){
					$error = $e -> getMessage();
					throw new UserAuthExceptions('Senden der Aktivierungs-/Passwort-Reset-Mail fehlgeschlagen! Fehler: "'.$error.'"');				
				}
				unset($actmail);	
				return TRUE;				
		}else{
			
			throw new UserAuthExceptions('Zum Senden einer Aktivierungs-/Passwort-Reset-Mail muss die Emailadresse gesetzt werden. Methode setEmail($emailadresse) benutzen.');			
		}	
	}	
	
	/**
	* ueberpruefen des Tokens aus der Aktivierungsmail
	* Wenn der Token stimmt wird der Account aktiviert und das Ablaufdatum, sowie der Token resettet
	* @param string $ftoken Aktivierungstoken
	* @return Bool TRUE bei verifiziertem Token, FALSE bei ungueltigem oder abgelaufenen Token
	*/
	public function verifyActRes($mtoken,$actorres = 0){		
		if(isset($mtoken)){	
			echo 'MTojen: '.$mtoken.'<br><br>';
			echo 'array $extoken: <pre>';
			echo base64_decode($mtoken);
			print_r($extoken = explode('.',base64_decode($mtoken)));
			echo '</pre><br><br>Userid: '.$this -> userid = $extoken[0].'<br><br>';
			echo '$ftoken: '.$ftoken = $extoken[1];
			try{	
				$dbquery = '
							SELECT 
								'.$this -> celltoken.','.$this ->celltokenexpire.' 
							FROM 
								'.$this -> usertab.' 
							WHERE 
								'.$this -> cellusername.' = ?
							OR
								'.$this -> cellemail.' = ?
							OR
								'.$this -> celluserid.' = ?
							LIMIT 1
							';
				$dbstmt = $this -> db -> prepare($dbquery);			
				$dbstmt -> bindValue(1,$this -> username ,PDO::PARAM_STR);
				$dbstmt -> bindValue(2,$this -> emailadress ,PDO::PARAM_STR);
				$dbstmt -> bindValue(3,$this -> userid ,PDO::PARAM_INT);
				$dbstmt -> execute();
				if($result = $dbstmt -> fetchall()){
					$date = new DateTime();
					$datenow = $date->format('Y-m-d');					
					if($result[0][$this -> celltokenexpire] >= $datenow){
						if($actorres == 1){
							$tokenhash = str_replace('.pwres','',$result[0][$this -> celltoken]);
						}else{
							$tokenhash = str_replace('.act','',$result[0][$this -> celltoken]);
						}
						if(password_verify($ftoken,$tokenhash)){
							if($actorres == 1){
								$wacstat = '';
							}else{
								$wacstat = $this -> cellactstat.' = "1",';
							}
							$dbquery = '
								UPDATE 
									'.$this -> usertab.' 
								SET 
									'.$this -> celltoken.' = "0", 
									'.$wacstat.'
									'.$this -> celltokenexpire.' = "0000-00-0 00:00:00"
								WHERE 
									'.$this -> celltoken.' = ?							
								';
								$dbstmt = $this -> db -> prepare($dbquery);	
								$dbstmt -> bindValue(1, $result[0][$this -> celltoken],PDO::PARAM_STR);									
								$dbstmt -> execute();	
								$countres = $dbstmt -> rowCount();
								if ($countres == 0){
									return FALSE;
								}else{
									return TRUE;
								}
						}else{
							return FALSE;
						}
					}else{
						return FALSE;
					}
				}else{
					return FALSE;
				}
				
			}
			catch (PDOException $e){
				$error = $e -> getMessage();				
				$trace = $e -> getTrace();
				$failquery = $trace[0]['args'][0];
				$line = $e -> getLine();
				throw new UserAuthExceptions('Fehler bei der Datenbankabfrage ! Fehler: "'.$error.'"; Zeile: "'.$line.'"; Query: "'.$failquery.'"');
			}
		}else{
			
			throw new UserAuthExceptions ('Zum verifizieren des Tokens muss dieser der Methode uebergeben werden. Beispiel: $uauth -> verifyActRes($token)');
			
		}
	}
	
	/***********************************************************
	*						Login-Methoden
	*
	*			Methoden rund um den Login von Benutzern
	************************************************************/
	
	/**
	* Methode zum Einloggen eines Benutzers ueber Benutzername/Email und Passwort
	*
	* @param $nameoremail Benutzername oder Email-Adresse uebergeben
	* @param $password Passwort uebergeben
	* @param $rememberme setzen bei Auswahl "Eingeloggt bleiben"
	* @return Bool TRUE oder FALSE
	*/	 
	public function doLogin($nameoremail,$password,$rememberme = 0){
		if(filter_var($nameoremail, FILTER_VALIDATE_EMAIL)){
			$this -> emailadress = $nameoremail;
		}else{
			$this -> username = $nameoremail;
		}
		$this -> password = $password;
		if (($this -> username == NULL || $this -> emailadress) && $this -> password == NULL){
			
			throw new UserAuthExceptions ('Zum Login eines Benutzers muessen die Email-Adresse oder der Benutzername UND das Passwort im Klartext an die Methode uebergeben werden. Beispiel: $uath -> doLogin($nameoremail,$password)');
			
		}else{
			if($this -> verifyPassword()){
				$this -> setSessionLoggedIn($rememberme);
				return TRUE;
			}else{
				return FALSE;
			}
		}
	}
	
	/**
	* Methode zum verifizieren des Passwortes.
	* Anschliessende Ueberpruefung ob der Passwort-Has erneuert werden muss 
	* inklusive generieren und speichern des neuen Hashes
	* 
	* return Bool False bei Nicht-Uebereinstimmung, TRUE bei Uebereinstimmung
	*/	 
	public function verifyPassword(){
		if(isset($this -> password) && (isset($this -> username) || isset($this -> emailadress)) && isset($this -> pepper)){
			try{
				$dbquery = '
							SELECT 
								'.$this -> cellpassword.','.$this -> celluserid.','.$this -> cellusername.','.$this -> cellemail.' 
							FROM 
								'.$this -> usertab.' 
							WHERE 
								'.$this -> cellusername.' = ?
							OR
								'.$this -> cellemail.' = ?
							LIMIT 1
							';
				$dbstmt = $this -> db -> prepare($dbquery);			
				$dbstmt -> bindValue(1, $this -> username,PDO::PARAM_STR);	
				$dbstmt -> bindValue(2, $this -> emailadress,PDO::PARAM_STR);				
				$dbstmt -> execute();
				$result = $dbstmt -> fetch();
				if(password_verify($this -> password.$this -> pepper,$result[$this -> cellpassword])){	
					$this -> username = $result[$this -> cellusername];
					$this -> emailadress = $result[$this -> cellemail];
					$this -> userid = $result[$this -> celluserid];
					if(password_needs_rehash($result[$this -> cellpassword],PASSWORD_DEFAULT)){					
						$hash = $this -> createPasswordHash();
						try{
							$dbquery = '
										UPDATE 
											'.$this -> usertab.' 
										SET 
											'.$this -> cellpassword.' = ? 
										WHERE 
											'.$this -> cellusername.' = ?
										';
							$dbstmt = $this -> db -> prepare($dbquery);			
							$dbstmt -> bindValue(1, $hash,PDO::PARAM_STR);	
							$dbstmt -> bindValue(2, $this -> username,PDO::PARAM_STR);							
							$dbstmt -> execute();	
						}
						catch (PDOException $e){
							$error = $e -> getMessage();				
							$trace = $e -> getTrace();
							$failquery = $trace[0]['args'][0];
							$line = $e -> getLine();
							throw new UserAuthExceptions('Fehler bei der Datenbankabfrage ! Fehler: "'.$error.'"; Zeile: "'.$line.'"; Query: "'.$failquery.'"');
						}
						return True;
					}else{
						return False;
					}
				}
			}
			catch (PDOException $e){
				$error = $e -> getMessage();				
				$trace = $e -> getTrace();
				$failquery = $trace[0]['args'][0];
				$line = $e -> getLine();
				throw new UserAuthExceptions('Fehler bei der Datenbankabfrage ! Fehler: "'.$error.'"; Zeile: "'.$line.'"; Query: "'.$failquery.'"');
			}	
		}else{			
			throw new UserAuthExceptions ('Um das Passwort verifizieren zu koennen muessen das Passwort, das Pepper sowie Benutzername oder Email-Adresse gesetzt sein. Methoden: setUsername($username), setEmail($emailadresse), setPassword($password). Das Pepper in den Standardeinstellungen setzen.');
			
		}		
	}
	
	/**
	* Pruefen und setzen des automatischen Login ("Eingeloggt bleiben")
	* Sollte der RememberMe-Cookie vorhanden sein wird der hash auf aktualitaet mit der Datenbank verglichen
	* Ist ein entsprechender Datensatz vorhanden wird der Benutzer mit der Methode setSession() eingeloggt.
	*
	* @return Boolean TRUE oder FALSE
	*/
	public function Autologin(){		
		if(!isset($_SESSION['loggedin'])){
			if (isset($_COOKIE['RememberMe'])){
				$data = explode('.',base64_decode($_COOKIE['RememberMe']));
				$this -> userid = $data[0];
				$this -> cookiesesshash = $data[1];
				try{
					$dbquery = '
									SELECT 
										'.$this -> cellsessuserid.','.$this ->cellsesshash.','.$this -> cellsessexpire.'
									FROM 
										'.$this -> sessiontab.' 
									WHERE 
										'.$this -> cellsessuserid.' = ?
									AND
										'.$this -> cellsesshash.' = ?
									AND 
										'.$this -> cellsessuagent.' = ?
									LIMIT 1
									';
					$dbstmt = $this -> db -> prepare($dbquery);			
					$dbstmt -> bindValue(1,$this -> userid ,PDO::PARAM_STR);
					$dbstmt -> bindValue(2,$this -> cookiesesshash ,PDO::PARAM_STR);
					$dbstmt -> bindValue(3,$_SERVER['HTTP_USER_AGENT'] ,PDO::PARAM_STR);
					$dbstmt -> execute();
					
					if($result = $dbstmt -> fetchall()){
						$date = new DateTime();
						$datenow = $date->format('Y-m-d');					
						if($result[0][$this -> cellsessexpire] >= $datenow){
							try{
								$dbquery = '
										SELECT 
											'.$this -> cellusername.','.$this -> cellemail.' 
										FROM 
											'.$this -> usertab.' 
										WHERE 
											'.$this -> celluserid.' = ?								
										LIMIT 1
										';
								$dbstmt = $this -> db -> prepare($dbquery);			
								$dbstmt -> bindValue(1,$this -> userid ,PDO::PARAM_STR);
								$dbstmt -> execute();
								$result = $dbstmt -> fetch();
								$this -> username = $result[$this -> cellusername];
								$this -> emailadress = $result[$this -> cellemail];
								
							}
							catch (PDOException $e){
								$error = $e -> getMessage();				
								$trace = $e -> getTrace();
								$failquery = $trace[0]['args'][0];
								$line = $e -> getLine();
								throw new UserAuthExceptions('Fehler bei der Datenbankabfrage ! Fehler: "'.$error.'"; Zeile: "'.$line.'"; Query: "'.$failquery.'"');
							}
							$this -> setSession(1,1);
							return TRUE;
						}else{
							$this -> userid = NULL;
							return FALSE;
						}
					}else{
						$this -> userid = NULL;
						return FALSE;
					}
				}
				catch (PDOException $e){
					$error = $e -> getMessage();				
					$trace = $e -> getTrace();
					$failquery = $trace[0]['args'][0];
					$line = $e -> getLine();
					throw new UserAuthExceptions('Fehler bei der Datenbankabfrage ! Fehler: "'.$error.'"; Zeile: "'.$line.'"; Query: "'.$failquery.'"');
				}
				
			}else{
				return FALSE;
			}
		}else{
			return FALSE;
		}
	}
	
	/**
	* Setzt die SessionVariablen und eventuell Cookies fuer den Login
	* 
	* @param $rememberme Wenn gesetzt, dann wird das Autologin aktiviert.
	*					 Es wird ein zufaelliger Hash generiert und in die 
	*					 Session Tabelle der DB eingetragen. Des weiteren
	*					 wird der RememberMe-Cookie gesetzt.
	* @param $refreshsesshash Wenn gesetzt, wird der alte Sessionhash durch einen neuen ersetzt.
	* @return Boolean TRUE 
	*/
	private function setSessionLoggedIn($rememberme = 0,$refreshsesshash = 0){
		session_regenerate_id(1);		
		$_SESSION ['loggedin'] = 1;
		$_SESSION ['userid'] = $this -> userid;
		$_SESSION ['username'] = $this -> username;
		$_SESSION ['email'] = $this -> emailadress;		
		if ($rememberme == 1){			
			$date = new DateTime();				
			Switch(substr($this -> sesshashexpire, -1, 1)){
				case 'Y':
					str_replace('Y','',$this -> sesshashexpire);
					$date->add(new DateInterval('P'.$this -> sesshashexpire.'Y'));
					break;
				case 'M':
					str_replace('M','',$this -> sesshashexpire);
					$date->add(new DateInterval('P'.$this -> sesshashexpire.'M'));
					break;
				case 'W':
					str_replace('W','',$this -> sesshashexpire);
					$date->add(new DateInterval('P'.$this -> sesshashexpire.'W'));
					break;
				case 'D':
					str_replace('D','',$this -> sesshashexpire);
					$date->add(new DateInterval('P'.$this -> sesshashexpire.'D'));
					break;
				case 'S':
					str_replace('S','',$this -> sesshashexpire);
					$date->add(new DateInterval('PT'.$this -> sesshashexpire.'H'));
					break;
				case 'i':
					str_replace('Y','',$this -> sesshashexpire);
					$date->add(new DateInterval('PT'.$this -> sesshashexpire.'M'));
					break;
				
			}
			$hashexpiredate = $date->format('Y-m-d H:i:00');
			$hashavailabe = 0;
			while($hashavailabe == 0){
				$sesshash = $this -> generateHash();
				try{				
					$dbquery = '
								SELECT 
									'.$this -> cellsesshash.'
								FROM 
									'.$this -> sessiontab.' 
								WHERE 
									'.$this -> cellsesshash.' = ?							
								';
					$dbstmt = $this -> db -> prepare($dbquery);	
					$dbstmt -> bindValue(1, $sesshash,PDO::PARAM_STR);				
					$dbstmt -> execute();
					if($result = $dbstmt -> fetchall()){
						$hashavailabe = 0;
					}else{
						$hashavailabe = 1;
					}
				}
				catch (PDOException $e){
					$error = $e -> getMessage();				
					$trace = $e -> getTrace();
					$failquery = $trace[0]['args'][0];
					$line = $e -> getLine();
					throw new UserAuthExceptions('Fehler bei der Datenbankabfrage ! Fehler: "'.$error.'"; Zeile: "'.$line.'"; Query: "'.$failquery.'"');
				}
			}
			if (empty($this -> userid)){
				$this -> setUserID();
			}
			if($refreshsesshash == 1){				
				try{				
					$dbquery = '
								UPDATE 
									'.$this -> sessiontab.' 
								SET 
									'.$this -> cellsesshash.' = ?,
									'.$this -> cellsessexpire.'=?
								WHERE 
									'.$this -> cellsesshash.' = ?	
								AND
									'.$this -> cellsessuserid.' = ?
								';
					$dbstmt = $this -> db -> prepare($dbquery);	
					$dbstmt -> bindValue(1, $sesshash,PDO::PARAM_STR);
					$dbstmt -> bindValue(2, $hashexpiredate,PDO::PARAM_STR);
					$dbstmt -> bindValue(3, $this -> cookiesesshash,PDO::PARAM_STR);
					$dbstmt -> bindValue(4, $this -> userid,PDO::PARAM_INT);				
					$dbstmt -> execute();				
				}
				catch (PDOException $e){
					$error = $e -> getMessage();				
					$trace = $e -> getTrace();
					$failquery = $trace[0]['args'][0];
					$line = $e -> getLine();
					throw new UserAuthExceptions('Fehler bei der Datenbankabfrage ! Fehler: "'.$error.'"; Zeile: "'.$line.'"; Query: "'.$failquery.'"');
				}
			}else{
				try{	
					
					$dbquery = '
								INSERT INTO 
									'.$this -> sessiontab.'
									(
									'.$this -> cellsessuserid.',
									'.$this -> cellsesshash.',
									'.$this -> cellsessexpire.',									
									'.$this -> cellsessuagent.'
									)
								VALUES
									(
									?,
									?,
									?,
									?
									)							
								';
					$dbstmt = $this -> db -> prepare($dbquery);	
					$dbstmt -> bindValue(1, $this -> userid,PDO::PARAM_STR);	
					$dbstmt -> bindValue(2, $sesshash,PDO::PARAM_STR);
					$dbstmt -> bindValue(3, $hashexpiredate,PDO::PARAM_STR);
					$dbstmt -> bindValue(4, $_SERVER['HTTP_USER_AGENT'],PDO::PARAM_STR);										
					$dbstmt -> execute();				
				}
				catch (PDOException $e){
					$error = $e -> getMessage();				
					$trace = $e -> getTrace();
					$failquery = $trace[0]['args'][0];
					$line = $e -> getLine();
					throw new UserAuthExceptions('Fehler bei der Datenbankabfrage ! Fehler: "'.$error.'"; Zeile: "'.$line.'"; Query: "'.$failquery.'"');
				}
			}		
			setCookie('RememberMe',base64_encode($this -> userid.'.'.$sesshash),strtotime($hashexpiredate));
			$this -> cookiesesshash = $sesshash;						
		}
		return TRUE;
	}
	
	/**
	* Methode zum pruefen des aktiven Login
	*
	* @return Boolean TRUE oder FALSE
	*/
	public function checkLogin(){
		if(isset($_SESSION['loggedin'])){
			if($_SESSION['loggedin'] == 1){
				return TRUE;
			}
			return FALSE;
		}
		return FALSE;
	}
	
	/**
	* Methode zum Logout des Benutzers
	* Alle Session-Variablen werden geloescht
	*
	* @return Boolean TRUE
	*/
	public function doLogout(){
		$_SESSION = array();
		return TRUE;
	}
	
	/***********************************************************
	*					Sonstige Methoden
	*
	*	Sonstige Methoden fuer die Arbeit mit dieser Klasse
	************************************************************/
	
	/**
	* Methode zum zuruecksetzen des Passwortes per Reset-Link-Mail
	*
	* @return Boolean TRUE oder FALSE
	*/
	public function doPasswordReset(){
		if(!empty($this -> emailadress) || !empty($this -> username) || !empty($this -> userid)){
			try{
				$dbquery = '
							SELECT 
								'.$this ->celltokenexpire.' 
							FROM 
								'.$this -> usertab.' 
							WHERE 
								'.$this -> cellusername.' = ?
							OR
								'.$this -> cellemail.' = ?
							OR
								'.$this -> celluserid.' = ?
							LIMIT 1
							';
				$dbstmt = $this -> db -> prepare($dbquery);			
				$dbstmt -> bindValue(1,$this -> username ,PDO::PARAM_STR);
				$dbstmt -> bindValue(2,$this -> emailadress ,PDO::PARAM_STR);
				$dbstmt -> bindValue(3,$this -> userid ,PDO::PARAM_INT);
				$dbstmt -> execute();
				if($result = $dbstmt -> fetchall()){
					$date = new DateTime();
					$datenow = $date->format('Y-m-d');	
					if($result[0][$this -> celltokenexpire] <= $datenow){
						$this -> generateActResToken(1);
						try{
							$dbquery = '
										UPDATE 
											'.$this -> usertab.' 
										SET 
											'.$this -> celltoken.' = ?,
											'.$this -> celltokenexpire.' = ?
										WHERE 
											'.$this -> cellemail.' = ?		
										OR
											'.$this -> cellusername.' = ?
										OR
											'.$this -> celluserid.' = ?
												
										';
							$dbstmt = $this -> db -> prepare($dbquery);	
							$dbstmt -> bindValue(1, $this -> dbtoken,PDO::PARAM_STR);
							$dbstmt -> bindValue(2, $this -> tokenexpiredatetime,PDO::PARAM_STR);
							$dbstmt -> bindValue(3, $this -> emailadress,PDO::PARAM_STR);	
							$dbstmt -> bindValue(4, $this -> username,PDO::PARAM_STR);			
							$dbstmt -> bindValue(5, $this -> userid,PDO::PARAM_INT);			
							$dbstmt -> execute();
							
						}
						catch(PDOException $e){
							$error = $e -> getMessage();				
							$trace = $e -> getTrace();
							$failquery = $trace[0]['args'][0];
							$line = $e -> getLine();
							throw new UserAuthExceptions('Fehler bei der Datenbankabfrage ! Fehler: "'.$error.'"; Zeile: "'.$line.'"; Query: "'.$failquery.'"');
						}
						if($this -> sendActResLink(1)){
							return TRUE;
						}else{
							return FALSE;
						}
					}else{
						return FALSE;
					}
				}
			}catch(PDOException $e){
				$error = $e -> getMessage();				
				$trace = $e -> getTrace();
				$failquery = $trace[0]['args'][0];
				$line = $e -> getLine();
				throw new UserAuthExceptions('Fehler bei der Datenbankabfrage ! Fehler: "'.$error.'"; Zeile: "'.$line.'"; Query: "'.$failquery.'"');
			}		
		}else{			
			throw new UserAuthExceptions('Zum Passwort-Reset muessen Benutzername,Email-Aresse oder BenutzerID gesetzt werden. Methoden, setUsername($username), setEmail($emailadresse), setUserID()');			
		}
	}
	
	/**
	* Aendert das Passwort des benutzers
	*
	* @return String generierter Token
	*/
	public function changePassword($password){
		if(!empty($this -> emailadress) || !empty($this -> username) || !empty($this -> userid)){
			$this -> password = $password;
			$phash = $this -> createPasswordHash();
			try{
				$dbquery = '
							UPDATE 
								'.$this -> usertab.' 
							SET 
								'.$this -> cellpassword.' = ?								
							WHERE 
								'.$this -> cellemail.' = ?		
							OR
								'.$this -> cellusername.' = ?
							OR
								'.$this -> celluserid.' = ?
									
							';
				$dbstmt = $this -> db -> prepare($dbquery);	
				$dbstmt -> bindValue(1, $phash,PDO::PARAM_STR);
				$dbstmt -> bindValue(2, $this -> emailadress,PDO::PARAM_STR);	
				$dbstmt -> bindValue(3, $this -> username,PDO::PARAM_STR);	
				$dbstmt -> bindValue(4, $this -> userid,PDO::PARAM_STR);					
				$dbstmt -> execute();
				
			}
			catch(PDOException $e){
				$error = $e -> getMessage();				
				$trace = $e -> getTrace();
				$failquery = $trace[0]['args'][0];
				$line = $e -> getLine();
				throw new UserAuthExceptions('Fehler bei der Datenbankabfrage ! Fehler: "'.$error.'"; Zeile: "'.$line.'"; Query: "'.$failquery.'"');
			}
		}else{
			
			throw new UserAuthExceptions('Zum aendern des Passwortes eines Benutzers muessen Benutzername,Email-Aresse oder BenutzerID gesetzt werden. Methoden, setUsername($username), setEmail($emailadresse), setUserID()');
			
		}
	}
	
	/**
	* Generiert einen Zufaelligen String und gibt diesen zurueck
	*
	* @return String generierter Token
	*/
	private function generateToken(){
		$chars = array(
						'a','b','c','d','e','f','g','h','j','k','m','n','p',
						'q','r','s','t','u','v','w','x','y','z','A','B','C',
						'D','E','F','G','H','J','K','M','N','P','Q','R','S',
						'T','U','V','W','X','Y','Z','1','2','3','4','5','6',
						'7','8','9',
						);
		$i = 0;
		$string = '';
		while($i < $this -> tokenlenght){
			$r = rand(0,54);
			$string .= $chars[$r];
			$i++;			
		}
		return $string;
		
	}
	
	/**
	* Generiert einen Zufaelligen Hash und gibt diesen zurueck
	*
	* @return String generierter Hash
	*/
	private function generateHash(){
		return bin2hex(openssl_random_pseudo_bytes($this -> hashlength));
	}	
}
?>