<?php

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

/**
 * Description of installer
 *
 * @author Igor Ratsun
 */
class installer {

    private $CI = '';
    public $module_image = '';
    public $last_error = '';

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

    public function set_last_error($error = '') {
        $this->last_error = $error;
    }

    /**
     * Add new resource
     * @param int $acl_resource_name
     * @param int $acl_resource_alias
     * @return mixed 
     */
    public function add_resource($acl_resource_name, $acl_resource_alias) {

        if (empty($acl_resource_name) || empty($acl_resource_alias)) {
            $this->set_last_error('add_resource: empty $acl_resource_name or $acl_resource_alias');
            return FALSE;
        }

        $data = array(
            'acl_resource_name' => $acl_resource_name,
            'acl_resource_alias' => $acl_resource_alias
        );

        $sel = $this->CI->db->
                        select('id_acl_resource')->
                        where($data)->
                        get('acl_resource')->row_array();

        if (!empty($sel['id_acl_resource'])) {
            $this->set_last_error('add_resource: resource exist');
            return FALSE;
        }

        $data['active'] = 1;

        $this->CI->db->insert('acl_resource', $data);

        $id = $this->CI->db->insert_id();

        if ($id == 0) {
            $this->set_last_error('add_resource: new resource wasn\'t inserted into acl_resource');
            return FALSE;
        }

        return $id;
    }

    /**
     * Insert new actions
     * @param int $id_resource
     * @param array $actions - array('action name' => 'action alias'). Ex. array('view' => 'Просмотрт', 'edit' => 'Редактирование')
     * @return boolean 
     */
    public function add_actions($id_resource = 0, $actions = array()) {
        if (empty($id_resource) || empty($actions)) {
            $this->set_last_error('add_actions: empty $id_resource or $actions');
            return FALSE;
        }

        $data = array();

        foreach ($actions as $name => $alias) {
            $data[] = array(
                'id_acl_resource' => $id_resource,
                'acl_action_name' => $name,
                'acl_action_alias' => $alias
            );
        }

        $this->CI->db->insert_batch('acl_action', $data);

        $id = $this->CI->db->insert_id();

        if ($id == 0) {
            $this->set_last_error('add_resource: new actions wasn\'t inserted into acl_action');
            return FALSE;
        }

        return TRUE;
    }

    /**
     * Add menu items to admin menu table
     * @param string $res_name
     * @param string $res_alias
     * @param array $menu_items - array(array('method', 'alias', 'img_link', 'acl_action')). 
     * Ex.array(
            array('project', 'Проекты', '', 'edit_portfolio_project'),
            array('image', 'Скриншоты', '', 'edit_portfolio_image'),
            array('partner', 'Партнеры', '', 'edit_portfolio_partner'),
            array('technology', 'Технологии', '', 'edit_portfolio_technology'),
            array('module', 'Модули', '', 'edit_portfolio_module')
        )
     * @param boolean $auto_page_prefix - if TRUE then page prefix will be set auto
     * @return boolean
     */
    private function add_menu_items_to_admin_menu($res_name, $res_alias, $menu_items = array(), $auto_page_prefix = TRUE) {
        if (empty($menu_items)) {
            $this->set_last_error('add_menu_items: empty $menu_items');
            return FALSE;
        }

        $this->CI->db->insert('admin_menu', array(
            'name' => $res_alias,
            'image' => $this->module_image,
            'acl_resource' => $res_name,
            'active' => 1
        ));

        $parent_id = $this->CI->db->insert_id();

        if (!empty($parent_id)) {
            // prepare menu items
            $ins_data = array();
            foreach ($menu_items as $v) {
                if (isset($v[0]) && isset($v[1]) && isset($v[2]) && isset($v[3])) {
                    $ins_data[] = array(
                        'page' => ($auto_page_prefix) ? 'mconfig/index/' . $res_name . '/' . $v[0] : $v[0],
                        'name' => $v[1],
                        'image' => $v[2],
                        'parent_id' => $parent_id,
                        'acl_resource' => $res_name,
                        'acl_action' => $v[3],
                        'active' => 1
                    );
                }
            }
            $this->CI->db->insert_batch('admin_menu', $ins_data);

            return TRUE;
        }

        return FALSE;
    }
    
    private function del_menu_items_from_admin_menu($res_name) {
        if (empty($res_name)) {
            $this->set_last_error('add_menu_items: empty $res_name');
            return FALSE;
        }

        $sql = $this->CI->db->
                        select('id_admin_menu, parent_id')->
                        where('acl_resource', $res_name)->
                        get('admin_menu')->result_array();

        if (empty($sql)) {
            return FALSE;
        }

        // Prepare data
        $del = array();
        foreach ($sql as $v) {
            $del[] = $v['id_admin_menu'];
        }
        $del[] = $v['parent_id'];

        if (count($del) > 0) {
            $this->CI->db->where_in('id_admin_menu', $del)->delete('admin_menu');
        }

        return ($this->CI->db->affected_rows() > 0);
    }

    /**
     * Install resource
     * @param string $res_name - Resource name in acl
     * @param string $res_alias - Resource alias in system
     * @param array $res_actions - array('action name' => 'action alias'). Ex. array('view' => 'Просмотрт', 'edit' => 'Редактирование')
     * @param array $menu_items - array(array('method', 'alias', 'img_link', 'acl_action'))
     * Ex.array(
            array('project', 'Проекты', '', 'edit_portfolio_project'),
            array('image', 'Скриншоты', '', 'edit_portfolio_image'),
            array('partner', 'Партнеры', '', 'edit_portfolio_partner'),
            array('technology', 'Технологии', '', 'edit_portfolio_technology'),
            array('module', 'Модули', '', 'edit_portfolio_module')
        )
     * @param boolean $auto_page_prefix - if TRUE then page prefix will be set auto
     * @return string 
     */
    public function install($res_name, $res_alias, $res_actions, $menu_items = array(), $auto_page_prefix = TRUE) {
        $id = $this->add_resource($res_name, $res_alias);

        if ($id !== FALSE 
                && $this->add_actions($id, $res_actions) 
                && (empty($menu_items) || $this->add_menu_items_to_admin_menu($res_name, $res_alias, $menu_items, $auto_page_prefix))) {

            return 'installed';
        }

        return $this->last_error;
    }

    /**
     * Uninstall resource
     * @param string $res_name
     * @return boolean
     */
    public function uninstall($res_name) {
        $sel = $this->CI->db->
                        select('id_acl_resource')->
                        where(array('acl_resource_name' => $res_name))->
                        get('acl_resource')->row_array();
        if (!empty($sel['id_acl_resource'])) {

            $id_resource = $sel['id_acl_resource'];

            // Clear action table
            $this->CI->db->delete('acl_action', array('id_acl_resource' => $id_resource));

            // Clear rule table
            $this->CI->db->delete('acl_rule', array('id_acl_resource' => $id_resource));

            // Clear resource table
            $this->CI->db->delete('acl_resource', array('id_acl_resource' => $id_resource));
            
            // Clear configuration table
            $this->CI->db->delete('configuration', array('id_acl_resource' => $id_resource));

            // Clear admin menu
            $this->del_menu_items_from_admin_menu($res_name);

            return TRUE;
        }

        return FALSE;
    }

}