<?php
/**
 * user.php - Controller for handling input pages.
 *
 * @author $Author: dtong $
 * @version $Id: user.php,v 1.53 2011/05/18 05:36:25 dtong Exp $
 * @copyright Copyright (c) 2009, Tiller Software Co., Ltd.
*/

require_once(APPPATH . 'libraries/mapping/display_list.php');

class User extends CI_Controller{
	//This is used as the session variable name. All admin features use this name
	private $divid = 'adminss'; //Used to be 'user'
	//To start a new display session or not
   private $new_display_session = FALSE;

	function __construct() {
      parent::__construct();
	 	$this->access_model->checkaccess_any('homepage_access');
	   $this->load->helper('form');
	   osa_load_lang('login');
	   osa_load_lang('admin');
	   $this->load->library('admin/admin_base');
	   $this->load->library('form_validation');
	   $this->load->model('auth/login_model');
	   $this->load->model('admin/user_model');
	   $this->load->model('admin/loginas_model');
	   $this->load->model('sort/searchsort_model');
	   osa_php_session_start();
	}

	function index() {
		$this->new_display_session = TRUE;
		$this->refresh(CMS_ADMIN_ENABLE);
	}

	function refresh($enableflag,$filter=FALSE,$page_con=FALSE) {
		$this->access_model->checkaccess_any('admin_system_management');
		if ( $enableflag != CMS_ADMIN_DISABLE && $enableflag != CMS_ADMIN_ENABLE && $enableflag != CMS_ADMIN_ALL ) {
			echo osa_ajaxmsg(lang('gen_internalservererror'));
			exit;
		}

	    //Add Config
		$url_add	 = 'admin/user/add/'.$enableflag;
		$div		 = 'user_input';
		$width		 = 550;
		$height		 = 450;
		$title_add	 = lang('admin_user_add_title');
		$imgaddname	 = osa_imagepath() . 'add_24.gif';
		$imgaddtitle = lang('admin_user_title_add');
	   $imgeadd     = $this->admin_base->newDhtmlWindow($url_add, $title_add, $width, $height, $div , $imgaddname,$imgaddtitle );
	 	//$divid    = 'user' ;
   	//$display  = $this->admin_base->init_display(CMS_ADMIN_USER_TYPE, $enableflag,$this->divid);
		if ( $this->new_display_session ) {
			$display = & $this->admin_base->init_display(CMS_ADMIN_USER_TYPE, $enableflag, $this->divid);
			$display->column_use_striptag[0] = TRUE;
			$display->column_use_striptag[2] = TRUE;
			$display->column_data_align[3] = 'center';
			$display->column_data_align[4] = 'center';
			$display->column_data_align[5] = 'center';
			$display->column_data_align[6] = 'center';
		}
		else {
			$this->load->library('search/searchutil');
			$display = & $this->searchutil->get_session($this->divid);
			$display->selectlistitem = $enableflag;
			$display->reset_data();
		}

   	$display->type = '';
   	$display->menu  = lang('admin_menu_user');
   	$display->search = lang('admin_user_search');
   	$display->pagetitle = lang('admin_user_title');
   	$display->titles = array(lang('admin_user_display_name'),
   				                 lang('admin_user_display_username'),
   				                 lang('admin_user_display_courses'),
   				                 lang('admin_user_display_lastlogin'),
   				                 lang('admin_user_display_lastfailedlogin'),
   				                 lang('admin_user_display_access'),
   				                 lang('admin_user_display_auth'),
   				                 lang('admin_user_display_enabled'),
   				                 "<span>$imgeadd</span>");
		$display->widths = array('20%', '10%', '30%', '7%', '7%', '8%', '8%', '5%', '5%');
		$page = 'page_content';
		$display->refresh = $page;
		$display->strand=array();
		$display->data_dep_sch =array();
		$display->standard =array();
		$display->filter=FALSE;
   	if ($filter != FALSE) {
			$display->filter = $filter;
   	}
		else {
			if (isset($_POST['filter']))
			$display->filter = $_POST['filter'];
		}
		//Fix (issue: 130) (issue:131)
		if ( !empty($display->filter) ) {
			$display->filter = rawurldecode($display->filter);
		}


	 	$data     = $this->user_model->get_alluser($enableflag,$display->filter);
		$splits = $this->admin_base->split($display->filter);
		if ($data != FALSE) {
			$user_recs = array();
			$course_recs = array();
			foreach($data as $record) {
				$user_recs[$record->id] = $record;
				if ( osa_is_int_one($record->courseid) && $record->courseenabled == CMS_DB_BOOLEAN_TRUE ) {
					if ( $record->iseditor ) {
						$coursename = "<a href='' onClick='return course_edit(\"{$record->courseid}\",\"{$enableflag}\")'>" .
										  "<span class='admin_uc_edit'>{$record->coursename}</span></a>";
					}
					else {
						$coursename = "<a href='' onClick='return course_read(\"{$record->courseid}\",\"{$enableflag}\")'>{$record->coursename}</a>";
					}
					if ( array_key_exists($record->id, $course_recs) ) {
						$course_recs[$record->id] .= ", $coursename";
					}
					else {
						$course_recs[$record->id] = "$coursename";
					}
				}
			}
			foreach ($user_recs as $rows) {
				$courses = '';
				if ( array_key_exists($rows->id, $course_recs) ) {
					$courses = & $course_recs[$rows->id];
				}
				$enabled = $rows->enabled;
				if ($rows->enabled == CMS_ADMIN_DISABLE){
					$rows->enabled  = '<div class="hide">'.lang('admin_list_convert_disabled').'</div>';
				    $imgdelname		= osa_imagepath() . 'enabled_16.gif';
				    $imgdeltitle	= lang('admin_user_title_enable');
				    $massage		= lang('admin_user_message_enable');
				}elseif ($rows->enabled == CMS_ADMIN_ENABLE){
					$rows->enabled  = '<div class="show">'.lang('admin_list_convert_enabled').'</div>';
				    $imgdelname		= osa_imagepath() . 'disable_16.gif';
				    $imgdeltitle	= lang('admin_user_title_disable');
				    $massage		= lang('admin_user_message_disable');
				}

				//Edit Config
				$url_edit		= 'admin/user/edit/'.$rows->id.'/'.$enableflag;
				$div			= 'user_input';
				$title_edit		= lang('admin_user_edit_title');
				$imgeditname	= osa_imagepath() . 'edit_16.gif';
				$imgedittitle	= lang('admin_user_title_edit');
				$linktitle		= lang('admin_user_link_title');

				//Delete Config
				$url_del		= 'admin/user/delete/'.$rows->id.'/'.$enabled.'/'.$enableflag;

				$displayname = osa_user_getname($rows);

				$highlight_name = $this->admin_base->highlight($splits, $displayname);

			    $linkname = $this->admin_base->linkDhtmlWindow($url_edit, $title_edit, $width, $height, $div ,$highlight_name,$linktitle );
			    $imgedit  = $this->admin_base->newDhtmlWindow($url_edit, $title_edit, $width, $height, $div , $imgeditname,$imgedittitle );
			    $imgdel   = $this->admin_base->delTarget($url_del, $page ,$massage,$imgdelname, $imgdeltitle);
			    //$imgedit  = '<span class="user_col_body_center_edit">' .$imgedit. '</span>';
			    //$imgdel   = '<span class="user_col_body_center_del">'  .$imgdel. '</span>';
             $row_buttons = "<nobr>$imgdel $imgedit</nobr>";
		 		//$temp = array($linkname , $rows->username, $rows->sis_teacher_number, $rows->access,$rows->auth,$rows->enabled, $imgdel, $imgedit);
		 		//$temp = array($linkname , $rows->username, $rows->sis_teacher_number, $rows->access, $rows->auth, $rows->enabled, $row_buttons);
		 		$temp = array($linkname , $rows->username, $courses, osa_date_format($rows->lastlogin, TRUE),
		 						  osa_date_format($rows->lastfailedlogin, TRUE), $rows->access, $rows->auth, $rows->enabled, $row_buttons);
				$display->add($temp);
			}
		}
		$this->admin_base->load_view($display);
	}

	function insert() {
		$this->access_model->checkaccess_any('admin_system_management');
		$data = array();

	   $userid = FALSE;
	   $keys = array_keys($_POST);

		$this->form_validation->set_rules('username', 'Username', 'required');
		if (array_key_exists('auth_id', $_POST) && $_POST['auth_id'] == CMS_AUTH_ID_LOCAL) {
			$this->form_validation->set_rules('password', 'Password', 'required');
		}
		$this->form_validation->set_rules('firstname', 'Firstname', 'required');
		$this->form_validation->set_rules('lastname', 'Lastname', 'required');
	    $this->form_validation->set_rules('email', 'Email', 'required|trim|valid_email') ;

		if ( ! $this->form_validation->run()) {
			echo osa_ajaxmsg(validation_errors());
			exit();
		}
		if (!array_key_exists('accessid', $_POST) || !osa_is_int($_POST['accessid']) || $_POST['accessid'] < 1 ) {
	 		echo osa_ajaxmsg(lang('admin_user_error_access') );
		   exit();
	 	}
	 	if (!array_key_exists('auth_id', $_POST) || !osa_is_int($_POST['auth_id']) || $_POST['auth_id'] < 1 ) {
	 		echo osa_ajaxmsg(lang('admin_user_error_auth') );
		   exit();
	 	}
		//Skip Field
	 	$skip_key = array('bustcache', 'id', 'accessname', 'authname');
	    foreach ($keys as $key) {
	    	if ( in_array($key , $skip_key)==FALSE ) {
	    	 	 $value = trim($_POST[$key]);
	    	 	  $key = strtolower($key);
	    	 	 if ($key == 'enabled') {
		    	  	 if ($_POST[$key] == 'on')
		    		 	 $value = CMS_ADMIN_ENABLE;
		    		 else
		    			 $value = CMS_ADMIN_DISABLE;
	    	 	 }
	    	 	 elseif ($key == 'password'){
						$modpass = $value . $this->config->item('cms_password_key');
		  				$value = md5($modpass);
	    	 	  }
			 	 elseif ($key == 'username'){
		  				$username = $value;
	    	 	  }
			 	elseif ($key == 'displayname'){
		  				$displayname = $value;
	    	 	  }
	    		 $data[$key] = $value;
			}
			elseif ($key == 'id') {
				$userid = $_POST[$key];
			}
	    }
	    /*
	    if ($displayname==FALSE || $displayname==''){
	    	$data['displayname']= $_POST['firstname']." " .$_POST['lastname'];
	    }
		*/
		$users = $this->user_model->get_user(FALSE, $username);
		if ($users!=FALSE) {
			echo osa_ajaxmsg( lang('admin_user_error_duplicate')  );
			exit();
		}

		$result=$this->user_model->add_user($data);
			if ($result==1)
			$result = 'success';
			echo $result;

	}

	//This is for the generic profile update
	function update1() {
		$this->_update_real(TRUE);
	}

	//This is for the admin update from the admin section
	function update() {
		$this->access_model->checkaccess_any('admin_system_management');
		$this->_update_real(FALSE);
	}

	//Updates a user record
	//This is run by non-admin users too. It is dangerous to put this code to handle both admin funtions and normal user functions.
	//The code has been reviewed to make sure no security hole but we should still separate the user roles to make it 100% safe.
	//TODO: Should separate non-admin users and admin users into different functions to be absolutely sure it is safe.
	//$skip_id_check is TRUE then it is from the generic profile else it is the admin update
	private function _update_real($skip_id_check=FALSE) {
		$data   = array();
	   $userid = FALSE;
	   $keys = array_keys($_POST);

	   $this->form_validation->set_rules('id', 'Id', 'trim|required') ;
	 	$this->form_validation->set_rules('username', 'Username', 'required');
	 	if ( array_key_exists('auth_id', $_POST) && $_POST['auth_id'] == CMS_AUTH_ID_LOCAL) {
	 		//Only asks for password if it is local authentication
			$this->form_validation->set_rules('password', 'Password', 'required');
	 	}
		$this->form_validation->set_rules('firstname', 'Firstname', 'required');
		$this->form_validation->set_rules('lastname', 'Lastname', 'required');
	    $this->form_validation->set_rules('email', 'Email', 'required|trim|valid_email') ;

		if ( ! $this->form_validation->run()) {
			echo osa_ajaxmsg(validation_errors());
		    exit();
		}

		if ($skip_id_check==FALSE){
			if (!array_key_exists('accessid', $_POST) || !osa_is_int($_POST['accessid']) || $_POST['accessid'] < 1 ) {
		 		echo osa_ajaxmsg(lang('admin_user_error_access') );
			   exit();
		 	}
		 	if (!array_key_exists('auth_id', $_POST) || !osa_is_int($_POST['auth_id']) || $_POST['auth_id'] < 1 ){
		 		echo osa_ajaxmsg(lang('admin_user_error_auth') );
			   exit();
		 	}
		}

	    //$password = '';
	    $skip = FALSE;
	    //Skip Field
	    $skip_key = array('bustcache', 'id', 'showpass', 'accessname', 'authname' );
	    foreach ($keys as $key) {
	    	if ( in_array($key , $skip_key)==FALSE ) {
	    	 	 $value = trim($_POST[$key]);
	    	 	 $key   = strtolower($key);
	    	 	 if ($key == 'enabled') {
		    	  	 if ($_POST[$key] == 'on')
		    		 	 $value = CMS_ADMIN_ENABLE;
		    		 else
		    		     $value = CMS_ADMIN_DISABLE;
	    	 	 } elseif ($value  == 'NO_PASSWORD'){
	    	 	 	     //$pass=$value;
	    	 	 		 $skip = TRUE;
	    	 	 } elseif ($key == 'password'){
	    	 	 		 $decrypted_pass = osa_des_decrypt($value);
	    	 	 		 if ( $decrypted_pass === FALSE ) {
	    	 	 		 	echo osa_ajaxmsg(lang('gen_internalservererror'));
	    	 	 		 	exit;
	    	 	 		 }
						 $modpass = $decrypted_pass . $this->config->item('cms_password_key');
		  				 $value = md5($modpass);
		  				 //$password  = $value;
	    	 	 }elseif ($key == 'comfirmpass'){
	    	 			 $skip = TRUE;
		  				 $comfirmpass  = $value;
	    	 	 }
	    		elseif ($key == 'displayname'){
		  				$displayname = $value;
	    	 	  }
	    	 	 if ( $skip == FALSE )
	    		     $data[$key] = $value;
	    		 $skip = FALSE;
			}
	    }

	   //////////////////////////////////////////////////////////////////////////////////////////////////////////
	   // Security rleated code, please do not change unless you are sure what you are doing
		if ( $skip_id_check ) {
			//Not checking means from the profile page and should not have these.
			//This prevents a security hole
			unset($data['accessid']);
			unset($data['auth_id']);
		}
		$userid = set_value('id');
   	$username = set_value('username');
   	$current_user = $this->login_model->getLogin();
		if ( !$current_user || !is_object($current_user) || !property_exists($current_user, 'id')) {
			//No session, impossible to happen but do exit anyway
			exit;
		}
		//This makes sure only admin can change other users' profiles
		if ( $current_user->id != $userid || $current_user->username != $username ) {
			//Modifying someone else's record so need admin premission, exit if no permission the line below
			$this->access_model->checkaccess_any('admin_system_management');
		}
	   $users = $this->user_model->get_user(FALSE, $username);
	   if ( $users ) {
	      if ($userid != $users->id) {
	      	//The user supplied id and username does not match
	      	//This is because admin is changing a user's username but the username already exists
		      echo osa_ajaxmsg( lang('admin_user_error_duplicate')  );
			   exit();
	      }
		}
		else {
			//Username does not exist - changing username here, only admin can do this
			$this->access_model->checkaccess_any('admin_system_management');
		}
		//////////////////////////////////////////////////////////////////////////////////////////////////////////

		 //Update the user record
		$result = $this->user_model->update_user($userid, $data);

		if (!empty($result)) {
			$result = 'success';
			//Refresh so we can see the changes in the site header
			$this->loginas_model->refresh_login_session($username);
		}
		else {
			$result = 'failed';
		}
		echo $result;
		exit;
	}

   function add($enableflag=FALSE) {
    	$this->edit(FALSE, $enableflag, CMS_ADMIN_ADD);
	}
/*
	function loginas($userid, $list) {
		// show error message
		if ( is_numeric($userid) == FALSE ){
			echo 'error list';
			return FALSE;
		}
		// show error message
		if ( is_numeric($list) == FALSE || $list < CMS_ADMIN_DISABLE || $list > CMS_ADMIN_ALL ) {
			echo 'error list';
			return FALSE;
		}
		$users = $this->user_model->get_user($userid);
		// show error message
		if ($users == FALSE) {
			echo 'show error message: no data';
			return FALSE;
		}

		$data = $users;
		$data->showhide        = $this->loginas_model->check_userauth($users->auth_id);
		$data->showhideloginas = $this->loginas_model->access_loginas();
		$data->showhideloginas = $this->loginas_model->check_sameuser($users->id);

		$this->edit($userid, $list, CMS_ADMIN_EDIT, $data);
	}
*/
	function edit($userid, $list, $action=CMS_ADMIN_EDIT, $data=FALSE) {
		$this->access_model->checkaccess_any('admin_system_management');
		// show error message
		if ( is_numeric($list) == FALSE || $list < CMS_ADMIN_DISABLE || $list > CMS_ADMIN_ALL ) {
			echo 'error list';
			return FALSE;
		}


	 	if ($data == FALSE && $action == CMS_ADMIN_EDIT ) {
			$users = $this->user_model->get_user($userid);
			// show error message
			if ($users==FALSE) {
				echo 'show error message: no data';
				return FALSE;
			}
			$data = $users;
			$data->showhide = $this->loginas_model->check_userauth($users->auth_id);
			//$data->showhideloginas = $this->loginas_model->access_loginas();
		   $data->showhideloginas = $this->loginas_model->check_sameuser($users->id);
			//$data->showhideloginas = $this->loginas_model->display_none();
		}

	    if ($action == CMS_ADMIN_ADD ) {
				$data->showhide        = $this->loginas_model->display_block();
				$data->showhideloginas = $this->loginas_model->display_none();
		  }
		  elseif ($action == CMS_ADMIN_EDIT ) {
				$data->password     = 'NO_PASSWORD';
		  }


		// get dropdown
	    $data->access     	  = $this->user_model->get_access();
	    $data->auth           = $this->user_model->get_auth();
	    $data->department     = $this->user_model->get_department();

	    $data->action     = $action;
	    $data->page       = $this->admin_base->getpage(CMS_ADMIN_USER_TYPE);
	    $data->selectlistitem = $list;

 		$selected_display='';

	    if ($action == CMS_ADMIN_EDIT ) {
	   		$selected_dep 			= $data->department_id;
	   		$selected_acc 			= $data->accessid;
	   		$selected_aut 			= $data->auth_id;
	   		//$selected_display 	= $data->firstname." " .$data->lastname;//osa_user_getname($data);
	   		$selected_display = osa_user_getname($data);
	    }
	    elseif ($action == CMS_ADMIN_ADD ) {
	    	$selected_dep = $data->department[0];
	   		$selected_acc = $data->access[0];
	   		$selected_aut = $data->auth[0];
	   		$selected_display=lang('admin_user_add_head');
	    }

	    $data->selected_dep = $selected_dep;
	   	$data->selected_acc = $selected_acc;
	   	$data->selected_aut = $selected_aut;
	   	$data->selected_display = $selected_display;
	   	$data->cms_admin_username =	$this->config->item('cms_admin_username');

	   	$this->CI =  get_instance();
		//$divid = 'user' ;
		$temp  = &$this->CI->searchsort_model->getSort($this->divid);

		$data->filter=$temp->filter;
	   $this->load->view('admin/user_input_view',$data);
	}

	//This is run by non-admin user
	function editprofile() {
	   $data = FALSE;
	   $data->page = $this->admin_base->getpage(CMS_ADMIN_USER_TYPE);
	   $data->department = $this->user_model->get_department();
		$row = osa_login_object();
		$user = $this->user_model->get_user($row->id);

		if ($user==FALSE || count($user)==0) {
			return FALSE;
		}
		$data->password = 'NO_PASSWORD';
   	$data->data = $user;
    	$data->selected_dep = $user->department_id;
	   $data->displayname = osa_user_getname($user);
	   if ( $this->config->item('cms_unit_admin_note_support') && $this->access_model->checkaccess_any_noexit('admin_unit_write') ) {
	   	$data->show_hide_unit_admin_note = TRUE;
	   	$data->hide_unit_admin_note_selections =
	   	array(0=>lang('admin_user_col_hide_unit_admin_note_yes'), 1=>lang('admin_user_col_hide_unit_admin_note_no'));
	   }
 	 	$this->load->view('admin/user_profile_view',$data);
	}

	function delete($userid, $enabled, $list) {
		$this->access_model->checkaccess_any('admin_system_management');

		if ( is_numeric($userid)==FALSE ||  is_numeric($enabled)==FALSE ||  is_numeric($list)==FALSE ) {
			// show error message
			return FALSE;
		}

		if ( $enabled < CMS_ADMIN_DISABLE && $enabled > CMS_ADMIN_ENABLE ) {
			// show error message
			return FALSE;
		}

		if ($enabled==CMS_ADMIN_DISABLE)
			$enabled= CMS_ADMIN_ENABLE;
		else
		    $enabled= CMS_ADMIN_DISABLE;

		$this->CI =  get_instance();
		//$divid = 'user' ;
		$user  = &$this->CI->searchsort_model->getSort($this->divid);

	    $filter= FALSE;
	    if ($user->filter!=FALSE && $user->filter!='')
	    $filter=$user->filter;

	   $this->user_model->del_user($userid, $enabled);
	   $this->refresh($list,$filter);
	}
/*
	function checkusername($list=FALSE, $action=CMS_ADMIN_EDIT) {
		$pass  = 'green';
		$error = 'red';
		$message = '';
		$html = '';
		$color = $error;
		$username='';
		$keys = array_keys($_POST);
	    foreach ($keys as $key) {
	    	$key = strtolower($key);
			if ($key == 'username') {
	    	 	$username = trim($_POST[$key]);
			}
	    }

	    if ($username == FALSE || $username == ''){
	     	$message = 'please enter username';
	    } else
	    {
		    $users = $this->user_model->get_user(FALSE, $username);
		    $message = 'username is available';
			if ($users == FALSE){
				$message = 'username is unavailable';
				$color = $pass;
			}
	    }

		$html  = '<span style="display: inline-block; width: 130px; ';
		$html .= 'border:solid 1px '.$color.'; color: '.$color.'; font-weight:bold; text-align: center;">';
		$html .= $message;
		$html .= '</span>';

		echo $html;

	}
*/
	//The admin user will be some other user and run this function.
	//Both loginas and go back to admin user
	function login($username, $loginas = CMS_ADMIN_ENABLE) {  // define cms_admin_loginas = 1
		//$this->access_model->checkaccess_any('admin_loginas', FALSE, FALSE, TRUE);
		return $this->loginas_model->loginas($username, $loginas);
	}
/*
	function search() {
	 $this->access_model->checkaccess_any('admin_system_management');
	 $keys = array_keys($_POST);
	    foreach ($keys as $key) {
	    	if ($key != 'bustcache') {
	    		$value = trim($_POST[$key]);
				if ($key == 'filter'){
					$filter = $value;
				}
				elseif ($key == 'filters'){
					$enableflag = $value;
				}
			}
	    }
    	echo $enableflag.'/'.$filter;
	}
*/

	function search() {
		$this->access_model->checkaccess_any('admin_system_management');
		$this->load->library('search/searchutil');
		$display = & $this->searchutil->get_session($this->divid);
		//$display->selectlistitem = $enableflag;
		$filter = FALSE;
		if ( array_key_exists('filter', $_REQUEST) ) {
			$filter = $_REQUEST['filter'];
		}
		$this->refresh($display->selectlistitem, $filter);
	}

	//Refreshes the header so we can see the name change. Non-admin users can run this.
	function update_header() {
		$this->load->view('template/header_view', array('user' => $this->login_model->getLogin()));
	}
}
?>