<?php defined('BASEPATH') OR exit('No direct script access allowed');
class Users extends Admin_Controller {
    /**
     * @var string
     */
    private $_redirect_url;
    /**
     * Constructor
     */
    function __construct() {
        parent::__construct();
        $this->load->model('UsersModel');
        // set constants
        define('REFERRER', "referrer");
        define('THIS_URL', base_url('admin/users'));
        define('DEFAULT_LIMIT', 10);
        define('DEFAULT_OFFSET', 0);
        define('DEFAULT_SORT', "last_name");
        define('DEFAULT_DIR', "asc");
        // use the url in session (if available) to return to the previous filter/sorted/paginated list
        if ($this->session->userdata(REFERRER)) {
            $this->_redirect_url = $this->session->userdata(REFERRER);
        } else {
            $this->_redirect_url = THIS_URL;
        }
        $this->add_js_theme('users_i18n.js', TRUE);
    }
    /**************************************************************************************
     * PUBLIC FUNCTIONS
     **************************************************************************************/
    /**
     * User list page
     */
    function index() {
        // get parameters
        $limit = $this->input->get('limit') ? $this->input->get('limit', TRUE) : DEFAULT_LIMIT;
        $offset = $this->input->get('offset') ? $this->input->get('offset', TRUE) : DEFAULT_OFFSET;
        $sort = $this->input->get('sort') ? $this->input->get('sort', TRUE) : DEFAULT_SORT;
        $dir = $this->input->get('dir') ? $this->input->get('dir', TRUE) : DEFAULT_DIR;
        // get filters
        $filters = array();
        if ($this->input->get('username')) {
            $filters['username'] = $this->input->get('username', TRUE);
        }
        if ($this->input->get('first_name')) {
            $filters['first_name'] = $this->input->get('first_name', TRUE);
        }
        if ($this->input->get('last_name')) {
            $filters['last_name'] = $this->input->get('last_name', TRUE);
        }
        // build filter string
        $filter = "";
        foreach ($filters as $key => $value) {
            $filter.= "&{$key}={$value}";
        }
        // save the current url to session for returning
        $this->session->set_userdata(REFERRER, THIS_URL . "?sort={$sort}&dir={$dir}&limit={$limit}&offset={$offset}{$filter}");
        // are filters being submitted?
        if ($this->input->post()) {
            if ($this->input->post('clear')) {
                // reset button clicked
                redirect(THIS_URL);
            } else {
                // apply the filter(s)
                $filter = "";
                if ($this->input->post('username')) {
                    $filter.= "&username=" . $this->input->post('username', TRUE);
                }
                if ($this->input->post('first_name')) {
                    $filter.= "&first_name=" . $this->input->post('first_name', TRUE);
                }
                if ($this->input->post('last_name')) {
                    $filter.= "&last_name=" . $this->input->post('last_name', TRUE);
                }
                // redirect using new filter(s)
                redirect(THIS_URL . "?sort={$sort}&dir={$dir}&limit={$limit}&offset={$offset}{$filter}");
            }
        }
        // get list
        $users = $this->UsersModel->get_all($limit, $offset, $filters, $sort, $dir);
        // build pagination
        $this->pagination->initialize(array('base_url' => THIS_URL . "?sort={$sort}&dir={$dir}&limit={$limit}{$filter}", 'total_rows' => $users['total'], 'per_page' => $limit));
        // setup page header data
        $this->set_title(lang('users_list'));
        $data = $this->includes;
        // set content data
        $content_data = array('this_url' => THIS_URL, 'users' => $users['results'], 'total' => $users['total'], 'filters' => $filters, 'filter' => $filter, 'pagination' => $this->pagination->create_links(), 'limit' => $limit, 'offset' => $offset, 'sort' => $sort, 'dir' => $dir);
        // load views
        $data['content'] = $this->load->view('admin/users/list', $content_data, TRUE);
        $this->load->view($this->template, $data);
    }
    /**
     * Add new user
     */
    function add() {
        // validators
        $this->form_validation->set_error_delimiters($this->config->item('error_delimeter_left'), $this->config->item('error_delimeter_right'));
        $this->form_validation->set_rules('username', lang('users input username'), 'required|trim|min_length[5]|max_length[30]|callback__check_username[]');
        $this->form_validation->set_rules('first_name', lang('users input first_name'), 'required|trim|min_length[2]|max_length[32]');
        $this->form_validation->set_rules('last_name', lang('users input last_name'), 'required|trim|min_length[2]|max_length[32]');
        $this->form_validation->set_rules('email', lang('users input email'), 'required|trim|max_length[128]|valid_email|callback__check_email[]');
        $this->form_validation->set_rules('language', lang('users input language'), 'required|trim');
        $this->form_validation->set_rules('status', lang('users input status'), 'required');
        $this->form_validation->set_rules('is_admin', lang('users input is_admin'), 'required');
        $this->form_validation->set_rules('password', lang('users input password'), 'required|trim|min_length[5]');
        $this->form_validation->set_rules('password_repeat', lang('users input password_repeat'), 'required|trim|matches[password]');
        if ($this->form_validation->run() == TRUE) {
            action_not_permitted();
            // save the new user
            $saved = $this->UsersModel->add_user($this->input->post());
            if ($saved) {
                $this->session->set_flashdata('message', sprintf(lang('admin_record_added_successfully'), $this->input->post('first_name', TRUE) . " " . $this->input->post('last_name', TRUE)));
            } else {
                $this->session->set_flashdata('error', sprintf(lang('admin_error_adding_record'), $this->input->post('first_name', TRUE) . " " . $this->input->post('last_name', TRUE)));
            }
            // return to list and display message
            redirect($this->_redirect_url);
        }
        // setup page header data
        $this->set_title(lang('add_user'));
        $data = $this->includes;
        // set content data
        $content_data = array('cancel_url' => $this->_redirect_url, 'user' => NULL, 'password_required' => TRUE);
        // load views
        $data['content'] = $this->load->view('admin/users/form', $content_data, TRUE);
        $this->load->view($this->template, $data);
    }
    /**
     * Edit existing user
     *
     * @param  int $id
     */
    function edit($id = NULL) {
        // make sure we have a numeric id
        if (is_null($id) OR !is_numeric($id)) {
            redirect($this->_redirect_url);
        }
        // get the data
        $user = $this->UsersModel->get_user($id);
        // if empty results, return to list
        if (!$user) {
            redirect($this->_redirect_url);
        }
        // validators
        $this->form_validation->set_error_delimiters($this->config->item('error_delimeter_left'), $this->config->item('error_delimeter_right'));
        $this->form_validation->set_rules('username', lang('users input username'), 'required|trim|min_length[5]|max_length[30]|callback__check_username[' . $user['username'] . ']');
        $this->form_validation->set_rules('first_name', lang('users input first_name'), 'required|trim|min_length[2]|max_length[32]');
        $this->form_validation->set_rules('last_name', lang('users input last_name'), 'required|trim|min_length[2]|max_length[32]');
        $this->form_validation->set_rules('email', lang('users input email'), 'required|trim|max_length[128]|valid_email|callback__check_email[' . $user['email'] . ']');
        $this->form_validation->set_rules('language', lang('users input language'), 'required|trim');
        $this->form_validation->set_rules('status', lang('users input status'), 'required');
        $this->form_validation->set_rules('is_admin', lang('users input is_admin'), 'required');
        $this->form_validation->set_rules('password', lang('users input password'), 'min_length[5]|matches[password_repeat]');
        $this->form_validation->set_rules('password_repeat', lang('users input password_repeat'), 'matches[password]');
        if ($this->form_validation->run() == TRUE) {
            action_not_permitted();
            // save the changes
            $saved = $this->UsersModel->edit_user($this->input->post());
            if ($saved) {
                $this->session->set_flashdata('message', sprintf(lang('admin_record_updated_successfully'), $this->input->post('first_name', TRUE) . " " . $this->input->post('last_name', TRUE)));
            } else {
                $this->session->set_flashdata('error', sprintf(lang('admin_error_during_update_record'), $this->input->post('first_name', TRUE) . " " . $this->input->post('last_name', TRUE)));
            }
            // return to list and display message
            redirect($this->_redirect_url);
        }
        // setup page header data
        $this->set_title(lang('admin_edit_user'));
        $data = $this->includes;
        // set content data
        $content_data = array('cancel_url' => $this->_redirect_url, 'user' => $user, 'user_id' => $id, 'password_required' => FALSE);
        // load views
        $data['content'] = $this->load->view('admin/users/form', $content_data, TRUE);
        $this->load->view($this->template, $data);
    }
    /**
     * Delete a user
     *
     * @param  int $id
     */
    function delete($id = NULL) {
        action_not_permitted();
        // make sure we have a numeric id
        if (!is_null($id) OR !is_numeric($id)) {
            // get user details
            $user = $this->UsersModel->get_user($id);
            if ($user) {
                // soft-delete the user
                $delete = $this->UsersModel->delete_user($id);
                if ($delete) {
                    $this->session->set_flashdata('message', sprintf(lang('admin_record_delete_successfully'), $user['first_name'] . " " . $user['last_name']));
                } else {
                    $this->session->set_flashdata('error', sprintf(lang('admin_error_during_delete_record'), $user['first_name'] . " " . $user['last_name']));
                }
            } else {
                $this->session->set_flashdata('error', lang('user_not_exist'));
            }
        } else {
            $this->session->set_flashdata('error', lang('user_id_required'));
        }
        // return to list and display message
        redirect($this->_redirect_url);
    }
    /**
     * Export list to CSV
     */
    function export() {
        // get parameters
        $sort = $this->input->get('sort') ? $this->input->get('sort', TRUE) : DEFAULT_SORT;
        $dir = $this->input->get('dir') ? $this->input->get('dir', TRUE) : DEFAULT_DIR;
        // get filters
        $filters = array();
        if ($this->input->get('username')) {
            $filters['username'] = $this->input->get('username', TRUE);
        }
        if ($this->input->get('first_name')) {
            $filters['first_name'] = $this->input->get('first_name', TRUE);
        }
        if ($this->input->get('last_name')) {
            $filters['last_name'] = $this->input->get('last_name', TRUE);
        }
        // get all users
        $users = $this->UsersModel->get_all(0, 0, $filters, $sort, $dir);
        if ($users['total'] > 0) {
            // manipulate the output array
            foreach ($users['results'] as $key => $user) {
                unset($users['results'][$key]['password']);
                unset($users['results'][$key]['deleted']);
                if ($user['status'] == 0) {
                    $users['results'][$key]['status'] = lang('admin_inactive');
                } else {
                    $users['results'][$key]['status'] = lang('admin_active');
                }
            }
            // export the file
            array_to_csv($users['results'], "users");
        } else {
            // nothing to export
            $this->session->set_flashdata('error', lang('core_error_no_results'));
            redirect($this->_redirect_url);
        }
        exit;
    }
    /**************************************************************************************
     * PRIVATE VALIDATION CALLBACK FUNCTIONS
     **************************************************************************************/
    /**
     * Make sure username is available
     *
     * @param  string $username
     * @param  string|null $current
     * @return int|boolean
     */
    function _check_username($username, $current) {
        if (trim($username) != trim($current) && $this->UsersModel->username_exists($username)) {
            $this->form_validation->set_message('_check_username', sprintf(lang('username_exist'), $username));
            return FALSE;
        } else {
            return $username;
        }
    }
    /**
     * Make sure email is available
     *
     * @param  string $email
     * @param  string|null $current
     * @return int|boolean
     */
    function _check_email($email, $current) {
        if (trim($email) != trim($current) && $this->UsersModel->email_exists($email)) {
            $this->form_validation->set_message('_check_email', sprintf(lang('user_email_exist'), $email));
            return FALSE;
        } else {
            return $email;
        }
    }
}
