<?php
require_once "app/class-user.php";
require_once "app/class-user-manager.php";

/**
 * User context
 *
 * Enables User management
 *
 * @author balexandre - Advantis Solutions
 * @version 1.0.1
 * @package Backend\Users
 *         
 */
class context_users extends context {
	public $contextname = "users";
	/**
	 * Constructor & Authorization
	 */
	function context_users() {
		main::check_auth_session ();
	}
	
	/**
	 * default action
	 */
	function index() {
		
		// $em = new EntityManager('users');
		// $user_list = $em->load("active=true");
		// $this->screen('users/index',$user_list);
		
		// GetUSers from View
		$main = new EntityManager ( User::LISTVIEW );
		$lista = $main->load ( 'active=true' );
		$this->screen ( 'users/index', $lista );
	}
	
	/**
	 * Prepares new user entry
	 *
	 * @param string $pvars        	
	 */
	function newuser($pvars = null) {
		$em = new EntityManager ( 'organisations' );
		
		$organisation_list = $em->load ( "active=true" );
		
		$orgtypes = array ();
		
		$available_roles = array ();
		
		if ($_REQUEST ["organisationid"]) {
			
			$orgid = $_REQUEST ["organisationid"];
			
			$available_roles = $this->get_available_roles ( $orgid );
		}
		
		$organisation_list = $em->load ( "active=true" );
		
		$this->screen ( "users/detail", array (
				'pvars' => $pvars,
				"organisation_list" => $organisation_list,
				"available_roles" => $available_roles 
		) );
	}
	
	/**
	 * returns available roles to user
	 *
	 * @param unknown $orgid        	
	 * @return multitype:
	 */
	function get_available_roles($orgid) {
		$roles = array ();
		
		$em = new EntityManager ( 'organisation_available_roles' );
		
		$roles = $em->load ( 'organisationid=?', array (
				$orgid 
		) );
		
		return $roles;
	}
	
	/**
	 * returns user roles by user id
	 *
	 * @param int $userid        	
	 * @return multitype:
	 */
	function get_userroles($userid) {
		$roles = array ();
		
		$em = new EntityManager ( 'userroles' );
		
		$list = $em->load ( "userid=?", array (
				$userid 
		) );
		
		foreach ( $list as $role ) {
			
			array_push ( $roles, $role->roleid );
		}
		
		return $roles;
	}
	
	/**
	 * Saves new user info for user creation
	 */
	function create() {
		
		// check errors
		if ($_POST ['passwd'] != $_POST ['confirm_passwd']) {
			
			return $this->newuser ( array (
					'error' => 1,
					'message' => R ( 'error_passwords_dont_match' ) 
			) );
		}
		
		if(!isset($_POST['roles']) || count($_POST['roles'])==0)
		{
			return $this->newuser ( array (
					'error' => 1,
					'message' => R ( 'error_msg_user_choose_roles' )
			) );						
		}
		//
		try {
			$needrollback = false;
			Transaction::beginTransaction ();
			
			$em = new EntityManager ( 'users' );
			
			$user = new User ();
			
			if ($_POST ["username"]) {
				
				$user->fullname = $_POST ["fullname"];
				$user->username = $_POST ["username"];
				$user->email = $_POST ["email"];
				$user->contact = $_POST ["contact"];
				$user->passwd = UserManager::generate_password ( $_POST ['passwd'] );
				$user->organisationid = $_POST ["organisationid"];
				
				// get language of org
				$org = new Entity ( "organisations", $user->organisationid );
				
				$user->languageid = $org->languageid;
				
				// end get language from org;
				
				$user = $em->create ( $user );
				$doneUser = $user->id;
				if ($doneUser > 0) {				
					$this->save_roles ( $user->id );
					
					//LogManagement::log ( "Create User:" . $user->username, "create", "Users", __LOGTYPE_SECURITY );
				} else { // error
					$needrollback = true;
					//LogManagement::log ( "Could not create user", "create", "Users", __LOGTYPE_SECURITY, __LOGLEVEL_ERROR );
				}
			}

			if ($needrollback) {
				Transaction::rollback ();
					
				LogManagement::log ( "New user error", "create", "users", __LOGTYPE_SECURITY, __LOGLEVEL_ERROR );
				setNotification ( getError ( "msg_error_new_user" ) , Notification::TYPE_ERROR);
			} else {
				Transaction::commit ();
				setNotification ( getSuccess ( "msg_new_user" ) );
				LogManagement::log ( "New user (" . $_POST ["username"] . ") created", "create", "users", __LOGTYPE_SECURITY );
			}
			} catch ( Exception $exp ) {
				Transaction::rollback ();
				dump_errorlog ( 'Users', 'create', $exp->getMessage () );
			}			
		
		header ( 'Location:' . __SITEBASE . '/' . $this->contextname );
	}
	
	/**
	 * Prepares user for editing by id
	 *
	 * @param string $pvars        	
	 */
	function edit($pvars = null) {
		$user = null;
		if ($_REQUEST ["id"]) {
			$user = new User ( $_REQUEST ["id"] );
		}
		
		$user_roles = $this->get_userroles ( $user->id );
		
		$available_roles = array ();
		
		$orgid = $_REQUEST ["organisationid"] ? $_REQUEST ["organisationid"] : $user->organisationid;
		
		$available_roles = $this->get_available_roles ( $orgid );
		
		$em = new EntityManager ( 'organisations' );
		
		$organisation_list = $em->load ( "active=true" );
		
		$this->screen ( 'users/detail', array (
				'user' => $user,
				'pvars' => $pvars,
				"available_roles" => $available_roles,
				"organisation_list" => $organisation_list,
				"user_roles" => $user_roles 
		) );
	}
	
	/**
	 * Save new data for user editing
	 */
	function save() {
		if ($_POST ["id"]) {
			
			$user = new User ( $_REQUEST ["id"] );
			
			if ($_POST ['btndisable']) {
				
				$user->active = false;
				$user->save ();
				// save e log
				
				setNotification ( getSuccess ( "msg_disable_user_ok" ) );
				LogManagement::log ( "Disable User:" . $user->username . " has been disabled ", "update", "Users", __LOGTYPE_SECURITY );
				
				header ( "Location:" . __SITEBASE ."/". $this->contextname );
			} else {
				
				// check errors
				
				if ($_POST ['passwd'] != $_POST ['confirm_passwd']) {
					
					return $this->edit ( array (
							'error' => 1,
							'message' => R ( 'error_passwords_dont_match' ) 
					) );
				}
				
				if(!isset($_POST['roles']) || count($_POST['roles'])==0)
				{
					return $this->edit ( array (
							'error' => 1,
							'message' => R ( 'error_msg_user_choose_roles' )
					) );
				}
				
				try {
					$needrollback = false;
					Transaction::beginTransaction ();
					
					$user->fullname = $_POST ["fullname"];
					$user->email = $_POST ["email"];
					$user->contact = $_POST ["contact"];
					
					if ($_POST ['password_changed']) {
						$user->passwd = UserManager::generate_password ( $_POST ['passwd'] );
					}
					// get language of org if user don't have languageid already
					if (! $user->languageid) {
						
						$org = new Entity ( "organisations", $user->organisationid );
						
						$user->languageid = $org->languageid;
					}
					// end get language from org;
					$this->save_roles ( $user->id );
					$user->save ();
					
					if ($needrollback) {
						Transaction::rollback ();
							
						LogManagement::log ( "Save user " . $user . " error", "update", "users", __LOGTYPE_DATA, __LOGLEVEL_ERROR );
						setNotification ( getError ( "msg_save_user_error" ) , Notification::TYPE_ERROR);
					} else {
						Transaction::commit ();
						setNotification ( getSuccess ( "msg_save_user_ok" ) );
						LogManagement::log ( "User:" . $user->username . " has been updated ", "update", "users", __LOGTYPE_SECURITY );
											}
				} catch ( Exception $exp ) {
					Transaction::rollback ();
					dump_errorlog ( 'Users', 'save', $exp->getMessage () );
					header ( 'Location:' . __SITEBASE . '/' . $this->contextname );
				}
				//LogManagement::log ( "User:" . $user->username . " has been updated ", "update", "users", __LOGTYPE_SECURITY );
				header ( 'Location:' . __SITEBASE . '/' . $this->contextname );
			}
		} else {
			LogManagement::log ( "User not found ", "create", "users", __LOGTYPE_SECURITY, __LOGLEVEL_ERROR );
			header ( 'Location:' . __SITEBASE . '/' . $this->contextname );
		}
	}
	
	/**
	 * Saves roles information associated to user
	 *
	 * @param int $userid        	
	 */
	function save_roles($userid) {
		
		// delete roles
		$da = new DataAccess ();
		$cfgdb = new ConfigDB ();
		$schema = $cfgdb->connections ["DEFAULT"] ["DBSCHEMA"];

		$da->func_get ("DELETE FROM " . $schema . ".userroles WHERE userid=:userid", array(':userid' => $userid)  );
		
		// re-assign roles
		$em = new EntityManager ( "userroles" );
		
		if (is_array ( $_POST ["roles"] )) {
			foreach ( $_POST ["roles"] as $roleid ) {
				
				$userrole = new stdClass ();
				$userrole->userid = $userid;
				$userrole->roleid = $roleid;
				
				$em->create ( $userrole );
			}
		}
	}
	
	/**
	 * Unblocks requested user ny id
	 */
	function unblockuser() {
		if ($_REQUEST ['id']) {
			
			$id = $_REQUEST ['id'];
			$user = new Entity ( "users", $id );
			
			if ($user->blocked) {
				$user->blocked = "false";
				$user->loginattempts = 0;
				
				$user->save ();
				setNotification ( getSuccess ( "msg_unblock_user_ok" ) );
				LogManagement::log ( "Unblocked user " .  $user->id , "update", "users", __LOGTYPE_DATA );
			}
		}
		
		header ( "Location:" . __SITEBASE . "/users/edit?id=" . $user->id );
	}
	
	/**
	 * validates if REquest user exists
	 */
	function userexists() {
		
		/**
		 * for access via REST
		 */
		$username = $_REQUEST ['username'];
		
		$em = new EntityManager ( "users" );
		
		$r = $em->load ( "username=?", array (
				$username 
		) );
		
		if ($r [0]) {
			echo 1;
		} else {
			echo 0;
		}
	}
}