<?php

/**
 * @author  Valiano
 * @copyright (C) 2012 Unite CMS, All Rights Reserved. 
 * @license GNU/GPLv3 http://www.gnu.org/licenses/gpl-3.0.html
 * */
defined('_JEXEC') or die('Restricted access');

class UniteCMSAdmin {

    protected $db;
	protected $view;
	protected $user;
	protected $errorMessage;
	
	public static $currentPath;
	
	
    /**
     * constructor
     */
    public function __construct() {
		
      	$this->db = new UniteMySql();
        $this->view = HelperAdmin::getGetVar("view", "galleries");
        
    }

    /********************************************************************
     **************** for users
     ******************************************************************* */

    /**
     * check user loged in or not
     * @return boolean islogedin
     */
    public function isLogedin() {
        $user = @$_SESSION["user"];
        
        if ($user) {
            return $user;
        }

        return false;
    }

    
    /**
     * validate that logged in
     */
    private function validateLoggedIn(){
    	if(empty($this->user))
    		HelperAdmin::throwError("Unauthorised access.");
    }
    
    /**
     * get current logged in user
     */
    private function getCurrentUser(){
    	$this->validateLoggedIn();
    	return($this->user);
    }
    
    
    /**
     * get current user id
     */
    private function getCurrentUserID(){
    	
    	$id = $this->getUserVar("id");
    	HelperAdmin::validateNotEmpty($id);
    	
    	return($id);
    }
    
    
    /**
     * get some variable from user array
     */
    private function getUserVar($key){
    	
    	$user = $this->getCurrentUser();
    	$value = HelperAdmin::getVal($this->user, $key);
    	return($value);
    }
    
    
    /**
     * check user loged in or not
     * @return boolean islogedin
     */
    public function isUserAdmin() {
    	
    	if($this->isLogedin() == false)
    		return(false);
    	
        $user = $this->getCurrentUser();
        if(!$user)
        	return(false);
        
        $role = HelperAdmin::getVal($user, "role");
        
        if($role == "admin")
        	return(true);
        
        return false;
    }

    
    /**
     * log user in
     * @return object user or redirect to login page if user does not exist
     */
    private function login() {
    	    	
    	$user = $this->isLogedin();
        if ($user) {
            return $user;
        }
        
        if(!isset($_POST["username"]))
        	return(false);
        
        $username = HelperAdmin::getPostVar("username");
        $password = HelperAdmin::getPostVar("password");
        
        if(empty($username)){
        	$this->setMessage("Empty username.","error");
        	return(false);
        }
        
        if(empty($password)){
        	$this->setMessage("Empty password.","error");
        	return(false);
        }
        
        $username = $this->db->escape($username);
        $password = $this->db->escape($password);
        $password = md5($password);
        
        $where = "username = '$username' and password = '$password'";
		$response = $this->db->fetch(ConfigCMS::$tableUsers, $where);
        
		if(empty($response)){
			$this->setMessage("Your username or password is incorrect. Please try again.","error");
			return(false);
		}
		
		$user = $response[0];
		$_SESSION["user"] = $user;
    }
	
    /**
     * update current user from database
     */
    private function updateCurrentUserSession(){
    	
    	$userID = $this->getCurrentUserID();
    	$user = $this->getUser($userID);
    	$this->user = $user;
    	$_SESSION["user"] = $user;
    }

    
    /**
     * log user out
     */
    private function logOut() {
    	
    	$this->unsetMessage();
    	
        session_destroy();
        $this->user = null;
        $this->redirect('login');
        exit;
    }
    
    
    
    
    /**
     * validate username for update
     */
    private function validateUsernameForUpdate($username, $currentID){
    	
    	$vwhere = "";
    	if(!empty($currentID))
    		$vwhere = " and id != " . $currentID;
    	
    	HelperAdmin::validateNotEmpty($username, "username");
    	
    	//validate username
    	$res = $this->db->fetch(DB_PRF . "users", " username = '" . $this->db->escape($username) . "' " . $vwhere);
    	if(!empty($res))
    		HelperAdmin::throwError("Failed to update username {$username} , already exists");
    }
    
    
    /**
     * validate email for update
     */
    private function validateEmailForUpdate($email, $currentID){
    	
    	$vwhere = "";
    	if(!empty($currentID))
    		$vwhere = " and id != " . $currentID;
    	    	
    	if(empty($email))
    		return(false);
    	
    	$res = $this->db->fetch(DB_PRF . "users", " email = '" . $this->db->escape($email) . "' " . $vwhere);
    	
    	if (!empty($res))
    		HelperAdmin::throwError("The email {$email} is already registered.");
    }

    /**
     * get all users to list
     * @param type $limit - number of user want to select (default is all)
     * @param type $start - select from this position
     * @return type
     */
    public function getUsers($limit = null, $start = 0) {
    
    	$user = $this->isLogedin();
    	$data = $this->db->fetch(ConfigCMS::$tableUsers);
    
    	$return = array();
    	$return['users'] = $data;
    	$return['total'] = count($data);
    	return $return;
    }
    
    /**
     * get user by Id
     * @return object user data
     */
    private function getUser($id) {
    
    	$id = (int)$id;
    	$id = $this->db->escape($id);
    
    	$data = $this->db->fetch(ConfigCMS::$tableUsers, "id=" . $id);
    	if(empty($data))
    		HelperAdmin::throwError("User with id: $id not found");
    
    	$user = $data[0];
    
    	return $user;
    }
    
    
    
    private function ____________OPERATIONS____________(){}
    
    /**
     * update profile from post
     */
    private function updateProfileFromPost() {
        
    	try{
    		    		
	    	$this->validateLoggedIn();
	    	$userID = $this->getCurrentUserID();
	   	
	    	$udata = array();
	        $udata["id"] = $userID;
	        $udata["name"] = HelperAdmin::getPostVar("name");
	        $udata["username"] = HelperAdmin::getPostVar("username"); 
	        $udata["email"] = HelperAdmin::getPostVar("email");
	        	        
	        $password = HelperAdmin::getPostVar("password");
	        if(!empty($password))
	            $udata["password"] = md5($password);
	        	        
	        $this->validateUsernameForUpdate($udata["username"], $userID);
	        $this->validateEmailForUpdate($udata["email"], $userID);
	        
	        //update user profile if all data is validated
	        $this->db->update(ConfigCMS::$tableUsers, $udata, "id =" . $udata["id"]);
        	
	        $this->updateCurrentUserSession();
	        
	        $this->setMessage("Profile successfully saved.", "success");
	        
    	}catch(Exception $e){
    		$message = $e->getMessage();
    		$this->setMessage("Update Failed: ".$message, "error");
    	}
            
    }
    
    /**
     * update user
     * @param type $data
     * @return int user id if add, and "false" if edit
     */
    private function updateUserFromPost() {
    
    	try{
    		
	    	$this->validateLoggedIn();
	    
	    	$userID = HelperAdmin::getPostVar("id");
	    	
	    	$isNew = empty($userID);
	    	
	    	if(!$isNew)
	    		$userID = (int)$userID;	//make it numeric
	    	
	    	$udata = array();
	    	
	    	if(!$isNew)
	    		$udata["id"] = $userID;
	    	
	    	$udata["name"] = HelperAdmin::getPostVar("name");
	    	$udata["username"] = HelperAdmin::getPostVar("username");
	    	$udata["email"] =  HelperAdmin::getPostVar("email");
	    	
	    	$role = HelperAdmin::getPostVar("role");
	    	if(!empty($role))
	    		$udata["role"] = $role;
	    	
	    	$password = HelperAdmin::getPostVar("password");
	    	if (!empty($password)) {
	    		$udata["password"] = md5($password);
	    	}
	    	
	    	//validate user
	    	$this->validateUsernameForUpdate($udata["username"], $userID);
	    	$this->validateEmailForUpdate($udata["email"], $userID);
	    
	    	if($isNew == false){		//update user
	    		
	    		$userID = $this->db->escape($userID);
	    		//update user
	    		$this->db->update(ConfigCMS::$tableUsers, $udata, "id=" . $userID);
	    		
	    		//update session if needed
	    		$currentUserID = $this->getCurrentUserID();
	    		if($currentUserID == $userID)
	    			$this->updateCurrentUserSession();
	    
	    		$this->setMessage("User successfully saved.", "success");
	    		
	    		return(false);
	    	}else{		//add new user
				
	    		$userID = $this->db->insert(ConfigCMS::$tableUsers, $udata);
	    		
	    		if(empty($userID))
	    			HelperAdmin::throwError("User not added!");
	    			
	    		$this->setMessage("User successfully added.", "success");
	    		$viewUser = HelperAdmin::getUrlView("edituser","id={$userID}");
	    		
	    		$this->redirect($viewUser,"url");
	    	}
    	
    	}catch(Exception $e){
    		$message = $e->getMessage();
    		$prefix = "Update Failed: ";
    		if($isNew == true)
    			$prefix = "Add user failed: ";
    			
    		$this->setMessage($prefix.$message, "error");
    	}
    	
    	return $userID;
    }
    
    
    /**
     * delete user account
     * @param type $userId - user need to delete
     * @return type
     */
    private function deleteUser($userId){
    	
    	$this->validateLoggedIn();
        $this->validateAdmin();
        
    	$cu = $this->isLogedin();
        
        if($cu["id"] == $userId){
            $this->setMessage("Can not delete your account.","error");
            return;
        }
        
        $userId = (int)$userId;
        $userId = $this->db->escape($userId);
        
        $this->db->delete(ConfigCMS::$tableUsers, "id = " . $userId);
        $this->setMessage("User successfully deleted.","success");
    }
    
    
    /**
     * create a random password
     * @param type $length - length of the password
     * @return string - random password
     */
    private function random_password( $length = 8 ) {
        $chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()_-=+;:,.?";
        $password = substr( str_shuffle($chars), 0, $length );
        return $password;
    }
    
    
    /**
     * reset password
     */
    public function resetPassword($email){
    	
    	try{
    		
	        if(empty($email))
	        	HelperAdmin::throwError("Email is required for reset password!");
	        
	        $email = $this->db->escape($email);
	        
	        $u = $this->db->fetch(ConfigCMS::$tableUsers, "email = '" .$email."'");
	        if(!$u)
	        	HelperAdmin::throwError("Password can not reset: Invalid email!");
				
	        $password = $this->random_password();

	          $data = array();
	          $data["password"] = md5($password);
	          $reset = $this->db->update(ConfigCMS::$tableUsers, $data, "email = '" .$email."'");

	           if($reset){
	              $send = $this->sendMail($email, $password);
	              if(!$send){
	              	
	              	//revert old password
	              	$user = $u[0];
	              	$oldPass = $user["password"];
	              	
	              	$data = array();
	              	$data["password"] = $oldPass;
	              	
	              	$reset = $this->db->update(ConfigCMS::$tableUsers, $data, "id=" .$user["id"]);
	              	
	              	$this->setMessage("The email could not be sent!","error");
	              	
	              }else
	               $this->setMessage("Your password successfuly reseted. Please check you email! <br>If you can not find email in your inbox, please check your spam folder.","success");               
	           }else{
	                $this->setMessage("Your password can not reset, please try again later!","error");
	           }
	        
	        $this->redirect("login");
        
    	}catch(Exception $e){
        	$message = $e->getMessage();
        	$this->setMessage("Reset Failed: ".$message, "error");
	        $this->redirect("login");
    	}
        
    }
    
    /**
     * send restore password email
     */
    public function sendMail($email,$password){
        
        $to = $email;
        $subject = SITE_TITLE .  " - Reset password";
        $txt = "Your new password is: " . $password;
        $txt .= "<br>Please login with this <a href='" . Uri::root()."admin/index.php?view=login'>link</a><br>" . Uri::root()."admin/index.php?view=login";
        $headers  = 'MIME-Version: 1.0' . "\r\n";
        $headers .= 'Content-type: text/html; charset=iso-8859-1' . "\r\n";
        $headers .= "From: noreply@".$_SERVER['SERVER_NAME'] ;
        $issent = mail($to,$subject,$txt,$headers);
        
       return $issent;
    }
    
    /******************************************************
     **** for Pages
     **************************************************** */

    /**
     * redirect
     * @param type $url
     */
    public static function redirect($view = "", $type="view") {
    	
    	if($type == "url"){
    		$url = $view;
    	}else{
    		$url = "index.php";
    		if(!empty($view))
    			$url .= "?view={$view}";
    	}
    	
        header('Location: ' . $url);
        exit;
    }

    

    /**
     * get the message
     */
    public function getMessage() {
        $message = @$_SESSION["message"];
        if ($message) {
            unset($_SESSION['message']);
            return $message;
        }

        return false;
    }

    
    /**
     * 
     * @param type $message - message that you want to display after redirect
     * @param type $type - type of message
     */
    private function setMessage($m, $type = "success") {
        $message["type"] = $type;
        $message["message"] = $m;
        $_SESSION["message"] = $message;
    }
    
    //unset message
    private function unsetMessage(){
    	unset($_SESSION["message"]);
    }
    
    
    /**
     * validate if the user is admin 
     */
    private function validateAdmin(){
    	
    	if(!$this->isUserAdmin()){
    		$this->redirect();
    		exit();
    	}
    }
    
    
    /**
     * set error view
     */
    private function setErrorView($message){
    	$this->view = "error";
    	$this->errorMessage = $message;
    }
    
    
    /**
     * validate if install folder exists
     */
    private function validateInstallFolder(){
    	
    	$pathInstall = ConfigCMS::$pathBase."install";
    	if(is_dir($pathInstall)){
    		$message = "Please remove the 'install' folder from the admin";
    		echo $message;
    		exit();
    	}
    }
    
    
    /**
     * run the admin
     */
    public function run(){
    	
    	$this->validateInstallFolder();
    	
    	$this->user = $this->isLogedin();
    	if(empty($this->user))
    		$this->user = $this->login();

    	if(empty($this->user) && isset($_POST["resetemail"])) {
    		$this->resetPassword($_POST["resetemail"]);
    		$this->redirect('login');
    		exit();
    	}
    	
    	//redirect to login
    	if(empty($this->user) && $this->view != 'login') {
    		$this->redirect('login');
    		exit();
    	}
    	
    	
    	switch($this->view){
    		case "login":
    			if($this->user)
    				$this->redirect("galleries");
    		break;
    		case "logout":
    			$this->logOut();
    			return(false);
    		break;
    		case "users":
    			$this->validateAdmin();
    			
    			if(!empty($_POST) && isset($_POST["did"])){
    				$this->deleteUser($_POST["did"]);
    				$this->redirect("users");
    			}
    			
   			break;
   			case "edituser":
   				$this->validateAdmin();
   				
   				if (!empty($_POST)) {
   					$nid = $this->updateUserFromPost();
   					
   					if (!$_POST["id"] && $nid) {
   						$page = @$_SESSION["page"] ? '&page='.($_SESSION["page"] + 1) : '';
   						$this->redirect("index.php?view=users".$page, "url");
   						exit;
   					}
   					$this->user = $this->isLogedin();
   				}
   			break;
   			case "profile":
   				if ($_POST) {
   					$this->updateProfileFromPost();
   					$this->user = $this->isLogedin();
   				}
   			break;
   			case 'mediaselect':
   			case 'ajax':
   				$pathGallery = ConfigCMS::$pathBase . '/unitegallery/unitegallery.php';
   				HelperAdmin::validateFilepath($pathGallery, "path to gallery");
   				
   				require_once $pathGallery;
   				exit();	
   			break;
    	}
    	
    	HelperAdmin::addScriptCommon("jquery", "jquery");
        HelperAdmin::addScript("jquery.validate.min", "template/js");
    	HelperAdmin::addScript("scripts", "template/js");
    	
    	$pathView = HelperAdmin::getPathView("main_view");
    	require $pathView;
    }
    
}

?>