<?php
class User 
{
	// Properties of the class:	
	var $edtName, $edtSurname, $edtEmail, $edtCell, $edtPhone, $edtPwd, $edtConfirm, $hddnUserCode,
		$edtImage, $companyId, $selType, $selGender, $edtPassportNo, $ppn, $ppc, $addresses,
		$selCountryCode, $editing, $selPosition;
		
	private $sdb;
	//The following function is actually the CONSTRUCTOR (note the same name as the class):
	function __construct()
	{
		$this->sdb = new SableDB();
		$this->editing = false;
	}
	
	// implement a __destruct() method
	public function __destruct(){unset($this->sdb);}		
	
	//Function for adding (registering) a new consultant:
	function addUser($silent=false)
	{
		$this->editing = !empty($this->hddnUserCode);

		/**
		if (!SableValidationFunctions::validateEmail($this->edtEmail)) 
			SableSystem::ajaxResponse(false, '', 'The email address provided does not seem to be valid.', 5, 
									 'edtEmail', false, 'edtEmail');
		**/
		
		if ($this->editing)
		{
			if ($this->edtPwd <> '') SableValidationFunctions::validatePassword($this->edtPwd);
			$this->updateUser();
		}
		else
		{
			if ($this->checkUserExists()) 
				SableSystem::ajaxResponse(false, '', 'This email address is already in use.', 5, 'edtEmail', false, 'edtEmail');
			$this->loadUser($silent);
		}
			
	} /* submitQuery() */
	
	function loadUser($silent=false)
	{   //two inserts need to be executed. 1. add the details to the Users table. This
	   //contains the user ID, Password and User Type (i.e. 'User' or 'trainer').
	   //Next, add the details of the consultant to the User table:

		$now = date('Y-m-d H:i:s');
		
		$this->edtImage 	= ''?'media/images/profile/profile.png':$this->edtImage;
		$this->companyId 	= $_SESSION['user']['company_id'] ? $_SESSION['user']['company_id'] : COMPANY_ID;
		$positionId			= $this->selPosition ? $this->selPosition : 5; //Groomer by default
		$accessId 			= SableDBfunctions::getAccessIdFromPositionId($positionId);
		
		//first generate a random password that the user must use to log in with the first time.
		//On first login, the user should be forced to change their password:
		if (empty($this->edtPwd)) $this->edtPwd = SableSystem::generateHash(8); //only 8 chars in length
		$active = $accessId == 4 ? 1 : 0;
		
		$insertQuery = "INSERT INTO user " .
					   "(user_email, user_password, user_image, user_cell, user_phone, user_surname, 
						user_name, company_id, access_id, user_active, position_id) VALUES (".
						"'".$this->edtEmail."', ".
						"'".password_hash($this->edtPwd, PASSWORD_DEFAULT)."', '".
						$this->edtImage."', '".
						$this->edtCell."','".
						$this->edtPhone."','".
						$this->edtSurname."','".
						$this->edtName."', ".
						$this->companyId.", ".
						$accessId.", ".
						$active." ,".
						$positionId.")"; //mechanics always active since they are not to receive activation emails.

		$res=$this->sdb->updateQuery($insertQuery);
		//Check if the user details were successfully added:
		if ($res)
		{
			$this->setUserCode(); //populates $this->hddnUserCode with the correct user_code from the DB.
			$this->storeAddresses($this->hddnUserCode);
			$this->addUserCompany(true);
			$this->addUserNotifications(array(array('value'=> 1), array('value' => 3)));
			if (!$userActive) $this->sendConfirmationLink();
			
			if ($silent) 
				return true;
			else
			{
				$uc = isset($_SESSION['user']['user_code']) ? $_SESSION['user']['user_code'] : 0;
				$txt = $uc ? "New user added: " : "New registration: ";
				SableDBFunctions::loadAuditDetail($uc, $txt.$this->edtEmail, $this->hddnUserCode);
				$this->setUserCode();
				if ($uc)
					SableSystem::ajaxResponse(true, '/user/', 'The user was successfully added.', 0, "", 0, "");
				else
				{
					SableSystem::ajaxPageRedirect('/user/done.php?'.base64_encode($this->hddnUserCode));
				}
			}
		}
		else 
			SableSystem::ajaxResponse(false, '', 'Registration of a new user failed. Please try again or contact support.', 0, 
									'edtName', true, 'edtName');
	}
	
	function updateUser()
	{   
		$uc 		 = SableSystem::sableDecode($this->hddnUserCode);
		$accessId 	 = SableDBfunctions::getAccessIdFromPositionId($this->selPosition);
		$updateQuery =	"UPDATE user set "		.
						"user_image = '"		. $this->edtImage		. "', " .
						"user_name = '" 		. $this->edtName		. "', " . 
						"user_surname = '"		. $this->edtSurname		. "', " . 
						"user_email = '"		. $this->edtEmail		. "', " . 
						"user_cell = '"			. $this->edtCell 		. "', " .
						"user_phone = '"		. $this->edtPhone 		. "', " .
						"access_id = "			. $accessId				. ", "  .
						"position_id = "		. $this->selPosition	. ", "  .
						"last_update = '"		. date('Y-m-d H:i:s')	."'";

		if (!empty($this->edtPwd)) $updateQuery .= ", user_password = '".password_hash($this->edtPwd, PASSWORD_DEFAULT)."' ";
		$updateQuery .= "where user_code = ".$uc;

		$res=$this->sdb->updateQuery($updateQuery);
		$this->storeAddresses($uc);
		//Check if the details were successfully added:
		if ($res)
		{
			SableDBFunctions::loadAuditDetail($_SESSION['user']['user_code'], 'User details modified: '.$this->edtEmail, $uc);
			//update the necessary fields for visual confirmation if the user is updating his own info:
			if ($_SESSION['user']['user_code'] == $uc)
			{
				$_SESSION['user']['user_image']   = $this->edtImage;
				$_SESSION['user']['user_name']    = $this->edtName;
				$_SESSION['user']['user_surname'] = $this->edtSurname;
			} SableSystem::ajaxResponse(true, '/user/', 'The user was successfully updated.', 0, '', 0, '');			  
		}
		else SableSystem::ajaxResponse(false, '', 'Modification of the user failed. Please try again or contact support.', 0, 'edtName', true, 'edtName');	
	}
	
	private function checkUserExists()
	{
		$cid = $this->sdb->getValue("select user_code from user where user_email = '".$this->edtEmail."' and deleted = 0");
		if (!empty($cid)) return true; else return false;
	}
	
	private function sendConfirmationLink()
	{
		$coyTitle = SableGeneralFunctions::setCoyTitle();
		$hash = base64_encode($this->createNewUserRequest());
		$link = SABLE_URL_ROOT.SableSystem::getCallPageLink('user/confirm.php?'.$hash);
		//$link = SABLE_SITE_URL."user/confirm.php?".sableEncode($this->edtEmail);
		$userName = SableDBFunctions::getUserDisplayName($this->edtEmail);
		$displayName = empty($userName) ? 'Sir/Madam' : $userName;
		$emailContent = 
		"<p>Dear ".$displayName.",</p>".
		"<p>You have been successfully registered on the ".$coyTitle." Database. In order to complete the registration process, please click on the following confirmation link:</p>".
		"<p><a href='".$link."'>Confirm Registration</a></p>".
		"<p>If clicking on the link above does not work, please copy and paste the following line into your browser's address bar:<br />".
		$link."</p>".
		"<p>Please take note of your log in credentials:<br />".
		"user name: <b>".$this->edtEmail."</b><br />".
		"password: <b>".$this->edtPwd."</b></p>";
		SableSystem::sendEmail($this->edtEmail, "Registration Confirmation", $emailContent);			
	} /* function sendConfirmationLink() */
	
	function viewUser()
	{
		$url = '/user/view.php?'.SableSystem::sableDecode($this->hddnUserCode);
		SableSystem::ajaxPageRedirect($url);
	}
	
	function editUser()
	{
		SableSystem::ajaxPageRedirect('/user/edit.php?'.SableSystem::sableDecode($this->hddnUserCode));
	}
	
	function copyUser()
	{
		$uc = SableSystem::sableDecode($this->hddnUserCode);
		$newId = $this->sdb->duplicateRow('user', 'user_code', $uc);
		if($newId)
		{
			SableDBFunctions::loadAuditDetail($_SESSION['user']['user_code'], 'user record duplicated: '.$this->edtName.' '.$this->edtSurname, $uc);
			SableSystem::ajaxPageRedirect('/user/','The user was successfully duplicated.');
		}
		else SableSystem::ajaxResponse(false, '', 'System error: The ccopy failed. Please try again later or contact support.', 0, '', false, '');
	}
	
	function deleteUser()
	{	
		$uc = SableSystem::sableDecode($this->hddnUserCode);	
		$cnt = $this->sdb->getValue("select count(*) as CNT from user where user_code = '".$uc."'");
		if ($cnt <= 0) 
			SableSystem::ajaxResponse(false, '', 'Delete failed - invalid user selected.', 0, '', false, '');	
		else
		{
			$sql = 'update user set deleted = 1 where user_code = '.$uc;
			$res = $this->sdb->updateQuery($sql);
			if ($res) 
			{
				SableDBFunctions::loadAuditDetail($_SESSION['user']['user_code'], 
				'User record deleted: '.$this->edtName.' '.$this->edtSurname, $uc);				
				SableSystem::ajaxPageRedirect('/user/','The user was successfully deleted.');
			}
			else
				SableSystem::ajaxResponse(false, '', 'System error: The user failed to delete. Please try again later or contact support.', 0, '', false, '');
		}		
	}
	
	private function createNewUserRequest()
	{
		//clear all previous user requests to avoid
		$sql = 'update user__request set expires = NULL where user_code = '.$this->hddnUserCode;
		$this->sdb->updateQuery($sql);
				
		//Create a temporary entry in the user__request table:
		$expires	= new DateTime();
		$expires->add(new DateInterval('PT24H'));
		$hash 		= SableSystem::generateHash(16);
		$sql = 'insert into user__request (user_code, expires, hash, ip_address) 
				values 
		('.$this->hddnUserCode.', "'.$expires->format('Y-m-d H:i:s').'", "'.$hash.'", "'.SableGeneralFunctions::getRealIpAddr().'");';
		//SableDebug::debug($sql);
		$res = $this->sdb->updateQuery($sql);
		if ($res) return $hash; else return false;
	}
		
	private function checkPassportNoExists()
	{
		global $sableDB;
		$code = SableSystem::SableDecode($this->hddnUserCode);
		$ppn = empty($this->edtPassportNo) || ($this->edtPassportNo === "undefined")?0:1;
		if ($ppn)
		{
			$sql = "select user_code from user where (user_passport = '".$this->edtPassportNo."')";
			if ($this->editing) $sql .= " and (user_code <> ".$code.")";
			$cid = $sableDB->getValue($sql);
			if ($cid) {return true;} else {return false;}
		} else {return false;}
	}
	
	private function storeAddresses()
	{		
		global $sableDB;
		if (is_array($this->addresses))
		{
			$addressIds = [];
			foreach($this->addresses as $addr)
			{
				/*
				$addr['tag'] = the address (address)
				$addr['value'] = address type (address_type_id)
				$this->selCountryCode = (country_id)
				*/
				$land = empty($this->selCountryCode) ? 197 : 0;
				$sql = 'insert ignore into address (address_type_id, country_id, address) 
						values ('.$addr['value'].', '.$land.', "'.$addr['tag'].'")';
				$sableDB->updateQuery($sql);
				$addressIds[]['value'] = $sableDB->getValue('select address_id from address 
				where address = "'.$addr['tag'].'" and address_type_id = '.$addr['value'].' and country_id = '.
				$land);
			}
			SableDBFunctions::storeArray('user__address', 'user_code', $this->hddnUserCode, 'address_id', $addressIds);
		}
	}
	
	private function setUserCode()
	{
		global $sableDB;
		$qry = "select user_code from user where user_email = '".$this->edtEmail."'";
		$this->hddnUserCode = SableSystem::sableEncode($sableDB->getValue($qry));
	}
	
	private function addUserNotifications($items)
	{
		$res = 	SableDBFunctions::storeArray('user__notification','user_code',$this->hddnUserCode,'notification_id', $items);
	}	
	
	private function addUserCompany($internal)
	{
		global $sableDB;
		$uc = SableSystem::sableDecode($this->hddnUserCode);
		$coId = SableSystem::sableDecode($this->companyId);
		
		$fields = "user_code, company_id";
		$values = $uc.", ".$coId;
		
		if ($this->edtStartDate) 
		{
			$sd = date('Y-m-d', strtotime($this->edtStartDate));
			$fields .= ", start_date";
			$values .= ", '".$sd."'";
		}
		
		if ($this->edtEndDate)
		{
			$ed = date('Y-m-d', strtotime($this->edtEndDate));
			$fields .= ", end_date";
			$values .= ", '".$ed."'";
		}
		
		$sql = "insert into user__company (".$fields.") values (".$values.")
		on duplicate key update company_id = ".$coId;
		if ($this->edtStartDate) $sql .= ", start_date = '".$sd."'";
		if ($this->edtEndDate)   $sql .= ", end_date   = '".$ed."'";
		$res = $sableDB->updateQuery($sql);
		
		if (!$internal)
		{
			if ($res)
				SableSystem::ajaxResponse(true, '/user/', 'The employee was successfully linked.', 0, "", 0, "");
			else
				SableSystem::ajaxResponse(false, "", "Failed to link the employee. Please try again or contact support.", 5, 
				"edtEmployee", false, "edtEmployee");	
		}
	}	
		
} /* Class User */
?>
