<?php

if (!defined('BASEPATH'))
    exit('No direct script access allowed');

class RT_user {

    public $id_user = 0;
    private $id_user_data_in_cookie = 'unique_user_information';
    private $CI;
    private $user_data;
    private $acl;

    function __construct() {
        $this->CI = & get_instance();

        $this->id_user = $this->CI->session->userdata('id_user');

        // Try set id_user from cookies
        if (empty($this->id_user)) {
            $this->_set_id_user_from_cookie();
        }

        $this->init_zend_acl();
        /**
         * @todo temporary solution for kcfinder
         */
        if ($this->isAllowed('resmng', 'file_manager') == TRUE || $this->isAllowed('filemanager', 'edit_file') == TRUE) {
            @session_start();
            $_SESSION['KCFINDER'] = array();
            $_SESSION['KCFINDER']['disabled'] = false;
            if ($this->id_user == -1 || $this->isAllowed('filemanager', 'edit_all_file')) {
                $_SESSION['KCFINDER_uploadURL'] = "/assets/uploads/multimedia";
            } else {
                $_SESSION['KCFINDER_uploadURL'] = "/assets/uploads/multimedia/images/" . $this->id_user;
            }
        }
    }

    /**
     * Set cookie
     */
    public function set_user_cookie() {
        $this->CI->load->helper('cookie');
        $cookie = array(
            'name' => $this->id_user_data_in_cookie,
            'value' => $this->id_user . ':' . $this->_create_user_cookie_hash($this->id_user),
            'expire' => '865000'
        );
        set_cookie($cookie);
    }

    /**
     * Logout
     */
    public function logout() {
        $this->CI->session->unset_userdata('id_user');
        $this->CI->load->helper('cookie');
        delete_cookie($this->id_user_data_in_cookie);
        /**
         * @todo temporary solution for kcfinder
         */
        if (!empty($_SESSION['KCFINDER'])) {
            $_SESSION['KCFINDER'] = array();
            $_SESSION['KCFINDER']['disabled'] = TRUE;
        }
    }

    private function _set_id_user_from_cookie() {
        $this->CI->load->helper('cookie');
        $data = get_cookie($this->id_user_data_in_cookie);
        $user_data = explode(':', $data);
        if (!empty($user_data[0]) && !empty($user_data[1])) {
            if ($user_data[1] == $this->_create_user_cookie_hash($user_data[0])) {
                $this->id_user = $user_data[0];
            }
        }
    }

    private function _create_user_cookie_hash($id_user = 0) {
        // Prepare data
        $id_user = intval($id_user);

        $this->CI->load->library('user_agent');
        // Get user passhash
        $q = $this->CI
                ->db
                ->select('password')
                ->where('id_acl_user', $id_user)
                ->where('active', '1')
                ->get('acl_user')
                ->row();
        $passhash = (isset($q->password)) ? $q->password : $this->CI->config->item('system_password_hash');

        return md5($this->CI->agent->agent_string() . $passhash . $id_user . $this->CI->config->item('encryption_key'));
    }

    /**
     * Initialize Zend ACL 
     */
    function init_zend_acl() {
        $this->CI->load->library('ciext/zend_init');
        if (empty($this->acl)) {
            // Init Zend ACL
            $this->acl = $this->CI->zend_init->Zend_ACL();

            // ADD Roles
            $roles = $this->CI->db->
                            select('t1.acl_role_name role1, t2.acl_role_name role2')->
                            join('acl_role t2', 't1.parent_id = t2.id_acl_role AND t2.active = TRUE', 'left')->
                            where('t1.active', 1)->
                            order_by('role2', 'ASC')->
                            get('acl_role t1')->result_array();

            foreach ($roles as $k => $v) {
                if (!empty($v['role2'])) {
                    $this->acl->addRole(new Zend_Acl_Role($v['role1']), $v['role2']);
                } else {
                    $this->acl->addRole(new Zend_Acl_Role($v['role1']));
                }
            }

            // ADD Resosrces
            $resources = $this->CI->db->
                            select('acl_resource_name')->
                            where('active', 1)->
                            get('acl_resource')->result_array();
            foreach ($resources as $k => $v) {
                $this->acl->add(new Zend_Acl_Resource($v['acl_resource_name']));
            }

            // ADD Rules
            $rules = $this->CI->db->
                            select('acl_role.acl_role_name, acl_resource.acl_resource_name, acl_action.acl_action_name')->
                            from('acl_role, acl_resource, acl_action, acl_rule')->
                            where('acl_role.id_acl_role = acl_rule.id_acl_role')->
                            where('acl_resource.id_acl_resource = acl_rule.id_acl_resource')->
                            where('acl_action.id_acl_action = acl_rule.id_acl_action')->
                            where('acl_role.active', TRUE)->
                            where('acl_resource.active', TRUE)->
                            get()->result_array();

            foreach ($rules as $k => $v)
                $this->acl->allow($v['acl_role_name'], $v['acl_resource_name'], $v['acl_action_name']);

            // Add all rights to system role
            $system_role = $this->CI->config->item('system_acl_role_name');
            $this->acl->addRole(new Zend_Acl_Role($system_role));
            $this->acl->allow($system_role, NULL, NULL);
        }
    }

    /**
     * Check role right
     * @param string $resource
     * @param string $action
     * @return boolean 
     */
    function isAllowed($resource, $action) {
        $role = $this->get_user_data('acl_role_name');
        return ($this->acl->hasRole($role) && $this->acl->has($resource) && $this->acl->isAllowed($role, $resource, $action));
    }

    /**
     * Get all user data
     * @param string $data
     * @return array 
     */
    public function get_user_data($data = 'login') {

        $id_acl_user = $this->id_user;

        // Check for empty id_user
        if (empty($id_acl_user)) {

            return FALSE;
        }

        if ($id_acl_user == -1) {
            $this->user_data['login'] = $this->CI->config->item('system_login');
            $this->user_data['acl_role_name'] = $this->CI->config->item('system_acl_role_name');
        }

        if (empty($this->user_data)) {
            $this->user_data = $this->CI->db->
                            select('au.login, ar.acl_role_name')->
                            join('acl_role ar', 'au.id_acl_role = ar.id_acl_role', 'left')->
                            where(array(
                                'au.id_acl_user' => intval($id_acl_user),
                                'au.active' => 1
                            ))->
                            get('acl_user au')->row_array();
        }

        return (!empty($this->user_data[$data])) ? $this->user_data[$data] : '';
    }

    /**
     * Set user data
     * @param string $key
     * @param mixed $value
     */
    public function set_user_data($key, $value) {
        $this->user_data[$key] = $value;
    }

    /**
     * Create password hash
     * @param string $password
     * @return string 
     */
    function password_hash($password) {
        return md5(md5($password . $this->CI->config->item('encryption_key')));
    }

    /**
     * Get id_user if exist else return 0
     * @param string $login
     * @param string $password
     * @return integer 
     */
    function get_user_id($login, $password) {

        // If system login
        if ($login == $this->CI->config->item('system_login') && $this->password_hash($password) == $this->CI->config->item('system_password_hash')) {
            $user['id_acl_user'] = -1;
        } else {
            $user = $this->CI->db->
                            select('id_acl_user')->
                            where(array(
                                'login' => mysql_real_escape_string($login),
                                'password' => $this->password_hash($password),
                                'active' => 1
                            ))->
                            get('acl_user')->row_array();
        }

        return (!empty($user['id_acl_user'])) ? $user['id_acl_user'] : 0;
    }

    /**
     * Login
     * @param string $login
     * @param string $password
     * @return int 
     */
    public function login($login, $password) {
        $this->id_user = $this->get_user_id($login, $password);
        if ($this->id_user == 0) {
            return 0;
        } else {
            $this->CI->session->set_userdata('id_user', $this->id_user);
            return $this->id_user;
        }
    }

    /**
     * Registration user
     * @param string $login
     * @param string $password
     * @param string $email
     * @param string $phone
     * @param string $role_name
     * @return boolean 
     */
    public function add_new_user($login, $password, $email = '', $phone = '', $id_acl_role = 0, $active = FALSE) {
        // prepare data
        $login = mysql_real_escape_string($login);
        $password = $this->password_hash($password);
        $email = mysql_real_escape_string($email);
        $phone = mysql_real_escape_string($phone);
        $id_acl_role = intval($id_acl_role);
        $active = (boolean) $active;

        $user = $this->CI->db->
                        select('id_acl_user')->
                        where(array(
                            'login' => $login,
                            'password' => $password
                        ))->
                        get('acl_user')->row_array();
        $user_id = 0;
        if (empty($user)) {
            // Add new user
            $data = array(
                'login' => $login,
                'password' => $password,
                'email' => $email,
                'phone' => $phone,
                'id_acl_role' => $id_acl_role,
                'active' => $active
            );
            $this->CI->db->insert('acl_user', $data);
            $user_id = $this->CI->db->insert_id();
        }

        return (empty($user_id)) ? FALSE : TRUE;
    }

    /**
     * Change user password
     * @param integer $id
     * @param string $pass
     * @return integer 
     */
    function change_pass($id, $pass) {
        $this->CI->db->update('acl_user', array('password' => $this->password_hash($pass)), array('id_acl_user' => intval($id)));
        $count = $this->CI->db->affected_rows();
        return $count;
    }

}
