<?php

/**
 * User registration class.
 *
 */
class ASRegisteruser extends ASDatabase{
    
    function __construct() {
       
        //connect to database
        parent::__construct("mysql", BKDB_HOST, BKDB_NAME, BKDB_USER, BKDB_PASS);
        
    }
    
    /**
     * Register user.
     * @param array $data User details provided during the registration process.
     */
    public function registeruser($data) {
        $user = $data['userData'];
        
        //validate provided data
        $errors = $this->_validateUser($data);
        
        if(count($errors) == 0) {
            //no validation errors
            
            //generate email confirmation key
            $key = $this->_generateKey();
            
            //insert new user to database
            $this->insert('as_users', array(
                "email"     => $user['email'],
                "username"  => strip_tags($user['username']),
                "password"  => $this->hashPassword($user['password']),
                "confirmation_key"  => $key,
				"confirmed"     => "Y",
                "register_date"     => date("Y-m-d"),
				"user_role"     => $user['user_role']    
            ));
            
			
            //prepare and output success message
            $result = array(
                "status" => "success",
                "msg"    => SUCCESS_ADDUSER
            );
            
            echo json_encode($result);
        }
        else {
            //there are validation errors
            
            //prepare result
            $result = array(
                "status" => "error",
                "errors" => $errors
            );
            
            //output result
            echo json_encode ($result);
        }
    }
    
    /**
     * Check if user with given username exist.
     * @param string $username Given username.
     * @return boolean TRUE if user already exist, false otherwise.
     */
    public function doesUserExist($username) {
        if(!$this->_isUsernameAvailable($username))
            return true;
        return false;
    }
    
    
    /**
     * Check if email already exist in database.
     * @param string $email Email to check.
     * @return boolean TRUE if email exist, FALSE otherwise
     */
    public function doesEmailExist($email) {
        return !$this->_isEmailAvailable($email);
    }
    
    
     
    /**
     * Hash given password.
     * @param string $password Unhashed password.
     * @return string Hashed password.
     */
     public function hashPassword($password) {
        //this salt will be used in both algorithms
        //for bcrypt it is required to look like this,
        //for sha512 it is not required but it can be used 
        $salt = "$2a$" . PASSWORD_BCRYPT_COST . "$" . PASSWORD_SALT;
        
        if(PASSWORD_ENCRYPTION == "bcrypt") {
            $newPassword = crypt($password, $salt);
        }
        else {
            $newPassword = $password;
            for($i=0; $i<PASSWORD_SHA512_ITERATIONS; $i++)
                $newPassword = hash('sha512',$salt.$newPassword.$salt);
        }
        
        return $newPassword;
     }
    
    
     /* PRIVATE AREA
     =================================================*/
    
    
    /**
     * Validate user provided fields.
     * @param array $data User provided fieds and id's of those fields that will 
     * be used for displaying error messages on client side.
     * @return array Array with errors if there are some, empty array otherwise.
     */
    private function _validateUser($data) {
        $id     = $data['fieldId'];
        $user   = $data['userData'];
        $errors = array();
        
        //check if email is not empty
        if($user['email'] == "")
            $errors[] = array( 
                "id"    => $id['email'],
                "msg"   => ERROR_EMAIL_REQUIRED 
            );
        
        //check if username is not empty
        if($user['username'] == "")
            $errors[] = array( 
                "id"    => $id['username'],
                "msg"   => ERROR_USERNAME_REQUIRED
            );
        
        //check if password is not empty
        if($user['password'] == "")
            $errors[] = array( 
                "id"    => $id['password'],
                "msg"   => ERROR_PASSWORD_REQUIRED
            );
        
        //check if password and confirm password are the same
        if($user['password'] != $user['confirm_password'])
            $errors[] = array( 
                "id"    => $id['confirm_password'],
                "msg"   => ERROR_PASSWORDS_DONT_MATCH
            );
        
        //check if email format is correct
        if(!$this->_validateEmail($user['email']))
            $errors[] = array( 
                "id"    => $id['email'],
                "msg"   => ERROR_EMAIL_WRONG_FORMAT
            );
        
        //check if email is available
        if($this->_isEmailAvailable($user['email']) == false)
            $errors[] = array( 
                "id"    => $id['email'],
                "msg"   => ERROR_EMAIL_TAKEN
            );
        
        //check if username is available
        if($this->_isUsernameAvailable($user['username']) == false )
            $errors[] = array( 
                "id"    => $id['username'],
                "msg"   => ERROR_USERNAME_TAKEN
            );
        
        
        return $errors;
    }
    
    
    /**
     * Check if email is available.
     * @param string $email Email to be checked.
     * @return boolean TRUE if email is available, FALSE otherwise
     */
    private function _isEmailAvailable($email) {
        $query = "SELECT * FROM `as_users` WHERE `email` = :e ";
        $result = $this->select($query, array( "e" => $email ));
        if(count($result) == 0)
            return true;
        else
            return false;
    }
    
    
    /**
     * Check if username is available.
     * @param string $un Username to check.
     * @return boolean TRUE if username is available, FALSE otherwise.
     */
    private function _isUsernameAvailable($un) {
        $query = "SELECT * FROM `as_users` WHERE `username` = :u ";
        $result = $this->select($query, array( "u" => $un ));
        if(count($result) == 0)
            return true;
        else
            return false;
    }
    
    
    /**
     * Check if email has valid format.
     * @param string $email Email to be checked.
     * @return boolean TRUE if email has valid format, FALSE otherwise.
     */
    private function _validateEmail($email) {
        return preg_match("/^[_a-z0-9-]+(\.[_a-z0-9+-]+)*@[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,})$/i", $email);
    }
    
    
    /**
     * Generate key used for confirmation and password reset.
     * @return string Generated key.
     */
    private function _generateKey() {
        return md5(time() . LOGIN_SALT . time());
    }
    
   
}

?>
