<?php
define('EXTENSION_NAME', "Custom Product Tab PRO");
define('EXTENSION_VERSION', "1.1.3");
define('EXTENSION_TYPE', "vQmod");
define('EXTENSION_COMPATIBILITY', "OpenCart 1.5.0.x, 1.5.1.x, 1.5.2.x, 1.5.3.x, 1.5.4.x and 1.5.5.x");
define('EXTENSION_URL', "http://www.opencart.com/index.php?route=extension/extension/info&extension_id=5557");
define('EXTENSION_SUPPORT', "support@agar.ee");
define('EXTENSION_SUPPORT_FORUM', "http://forum.opencart.com/viewtopic.php?f=123&t=56392");

if (!function_exists('utf8_strlen')) {
    function utf8_strlen($string) {
        return strlen(utf8_decode($string));
    }
}

class ControllerModuleCustomProductTab extends Controller {
    private $error = array();
    private $defaults = array(
        'cpt_installed'                     => 1,
        'custom_product_tab_status'         => 0,
        'cpt_always_show'                   => 0,
        'cpt_use_admin_language_value'      => 1,
        'cpt_use_default_for_new'           => 1,
        'cpt_remove_sql_changes'            => 0
    );

    public function index() {
        $this->data = array_merge($this->data, $this->language->load('module/custom_product_tab'));

        $this->document->setTitle($this->language->get('heading_title'));

        $this->load->model('setting/setting');
        $this->load->model('module/custom_product_tab');

        if (($this->request->server['REQUEST_METHOD'] == 'POST') && $this->validateForm()) {
            $checkbox_settings = array(
                'cpt_always_show',
                'cpt_use_admin_language_value',
                'cpt_use_default_for_new',
                'cpt_remove_sql_changes'
            );

            # Loop through all settings for the post/config values
            foreach ($checkbox_settings as $checkbox_setting) {
                if (!isset($this->request->post[$checkbox_setting])) {
                    $this->request->post[$checkbox_setting] = 0;
                }
            }

            $tabs = (isset($this->request->post['tabs']) && is_array($this->request->post['tabs'])) ? $this->request->post['tabs'] : array();

            unset($this->request->post['tabs']);

            $this->model_setting_setting->editSetting('custom_product_tab', $this->request->post);

            foreach ($tabs as $tab) {
                $this->model_module_custom_product_tab->editTab($tab['tab_id'], $tab);
            }

            $this->session->data['success'] = $this->language->get('text_success');

            $this->redirect($this->url->link('extension/module', 'token=' . $this->session->data['token'], 'SSL'));
        }

        if ($this->checkDatabaseStructure()) {
            $tabs = $this->model_module_custom_product_tab->getTabs();
            $tab_data = array();

            foreach ($tabs as $tab) {
                if (isset($this->request->post['tabs']) && is_array($this->request->post['tabs'])) {
                    foreach ($this->request->post['tabs'] as $t) {
                        if ($tab['tab_id'] == $t['tab_id']) {
                            $t['names'] = $t['name'];
                            $t['defaults'] = $t['default'];
                            $name = $tab['name'];

                            if (isset($t['linked_products']) && is_array($t['linked_products'])) {
                                $this->load->model('catalog/product');
                                $t['linked_product_names'] = array();
                                foreach ($t['linked_products'] as $product_id) {
                                    $product = $this->model_catalog_product->getProduct($product_id);
                                    $t['linked_product_names'][$product_id] = "${product['name']} (${product['model']})";
                                }
                            }

                            $tab = array_merge($tab, $t);
                            $tab['name'] = $name;
                        }
                    }
                } else {
                    $tab['names'] = $this->model_module_custom_product_tab->getTabNames($tab['tab_id']);
                    $tab['defaults'] = $this->model_module_custom_product_tab->getTabDefaults($tab['tab_id']);
                }
                $tab_data[] = $tab;
            }

            $this->data['tabs'] = $tab_data;
        } else {
            $this->data['tabs'] = array();
        }

        if (isset($this->error['warning'])) {
            $this->data['error_warning'] = $this->error['warning'];
        } else {
            $this->data['error_warning'] = '';
        }

        if (!class_exists('VQMod')) {
            $this->data['error_warning'] = $this->language->get('error_vqmod');
        }

        if (isset($this->error['tab_name'])) {
            $this->data['error_tab_name'] = $this->error['tab_name'];
        } else {
            $this->data['error_tab_name'] = array();
        }

        if (isset($this->session->data['success'])) {
            $this->data['success'] = $this->session->data['success'];

            unset($this->session->data['success']);
        } else {
            $this->data['success'] = '';
        }

        $this->data['breadcrumbs'] = array();

        $this->data['breadcrumbs'][] = array(
            'text'      => $this->language->get('text_home'),
            'href'      => $this->url->link('common/home', 'token=' . $this->session->data['token'], 'SSL'),
            'separator' => false
        );

        $this->data['breadcrumbs'][] = array(
            'text'      => $this->language->get('text_module'),
            'href'      => $this->url->link('extension/module', 'token=' . $this->session->data['token'], 'SSL'),
            'separator' => ' :: '
        );

        $this->data['breadcrumbs'][] = array(
            'text'      => $this->language->get('heading_title'),
            'href'      => $this->url->link('module/custom_product_tab', 'token=' . $this->session->data['token'], 'SSL'),
            'separator' => ' :: '
        );

        $this->data['action'] = $this->url->link('module/custom_product_tab', 'token=' . $this->session->data['token'], 'SSL');

        $this->data['cancel'] = $this->url->link('extension/module', 'token=' . $this->session->data['token'], 'SSL');

        $this->data['add_tab_url'] = html_entity_decode($this->url->link('module/custom_product_tab/add', 'token=' . $this->session->data['token'], 'SSL'));
        $this->data['remove_tab_url'] = html_entity_decode($this->url->link('module/custom_product_tab/remove', 'token=' . $this->session->data['token'], 'SSL'));

        $this->data['ext_name'] = EXTENSION_NAME;
        $this->data['ext_version'] = EXTENSION_VERSION;
        $this->data['ext_type'] = EXTENSION_TYPE;
        $this->data['ext_compatibility'] = EXTENSION_COMPATIBILITY;
        $this->data['ext_url'] = EXTENSION_URL;
        $this->data['ext_support'] = EXTENSION_SUPPORT;
        $this->data['ext_support_forum'] = EXTENSION_SUPPORT_FORUM;
        $this->data['ext_subject'] = sprintf($this->language->get('text_ext_subject'), EXTENSION_NAME);

        $this->load->model('localisation/language');
        $this->data['languages'] = $this->model_localisation_language->getLanguages();

        $this->load->model('catalog/category');
        $this->data['categories'] = $this->model_catalog_category->getCategories(0);
        $this->data['token'] = $this->session->data['token'];

        # Loop through all settings for the post/config values
        foreach (array_keys($this->defaults) as $setting) {
            if (isset($this->request->post[$setting])) {
                $this->data[$setting] = $this->request->post[$setting];
            } else {
                $this->data[$setting] = $this->config->get($setting);
                if ($this->data[$setting] === null) {
                    $this->data['error_warning'] = $this->language->get('error_unsaved_settings');
                    if (isset($this->defaults[$setting])) {
                        $this->data[$setting] = $this->defaults[$setting];
                    }
                }
            }
        }

        $this->template = 'module/custom_product_tab.tpl';
        $this->children = array(
            'common/header',
            'common/footer'
        );

        $this->response->setOutput($this->render());
    }

    public function install() {
        $this->language->load('module/custom_product_tab');

        $this->db->query("CREATE TABLE IF NOT EXISTS " . DB_PREFIX . "product_tab (tab_id INT(11) NOT NULL AUTO_INCREMENT, sort_order INT(3) NOT NULL, status TINYINT(1) NOT NULL DEFAULT '0', editable TINYINT(1) NOT NULL DEFAULT '1', PRIMARY KEY (tab_id)) ENGINE=MyISAM  DEFAULT CHARSET=utf8 COLLATE=utf8_bin");
        $this->db->query("CREATE TABLE IF NOT EXISTS " . DB_PREFIX . "product_tab_name (tab_id INT(11) NOT NULL, language_id INT(11) NOT NULL, name VARCHAR(64) COLLATE utf8_bin NOT NULL, PRIMARY KEY (tab_id, language_id)) ENGINE=MyISAM  DEFAULT CHARSET=utf8 COLLATE=utf8_bin");
        $this->db->query("CREATE TABLE IF NOT EXISTS " . DB_PREFIX . "product_tab_default (tab_id INT(11) NOT NULL, language_id INT(11) NOT NULL, content TEXT COLLATE utf8_bin NOT NULL, PRIMARY KEY (tab_id, language_id)) ENGINE=MyISAM  DEFAULT CHARSET=utf8 COLLATE=utf8_bin");
        $this->db->query("CREATE TABLE IF NOT EXISTS " . DB_PREFIX . "product_tab_content (product_id INT(11) NOT NULL, language_id INT(11) NOT NULL, tab_id INT(11) NOT NULL, content TEXT COLLATE utf8_bin NOT NULL, PRIMARY KEY (product_id, language_id, tab_id)) ENGINE=MyISAM  DEFAULT CHARSET=utf8 COLLATE=utf8_bin");

        $this->load->model('localisation/language');
        $languages = $this->model_localisation_language->getLanguages();

        // If upgrading, do not add the initial values
        $query = $this->db->query("SELECT COUNT(*) as count FROM " . DB_PREFIX . "product_tab WHERE tab_id <= '4'");

        if ((int)$query->row['count'] == 0) {
            $tabs = array();
            $tabs[] = array("id" => 1, "name" => $this->language->get("tab_description"));
            $tabs[] = array("id" => 2, "name" => $this->language->get("tab_attribute"));
            $tabs[] = array("id" => 3, "name" => $this->language->get("tab_review"));
            $tabs[] = array("id" => 4, "name" => $this->language->get("tab_related"));

            $this->db->query("INSERT INTO " . DB_PREFIX . "product_tab (tab_id, sort_order, status, editable) VALUES (1, 10, 1, 0), (2, 20, 1, 0), (3, 30, 1, 0), (4, 40, 1, 0)");

            foreach ($tabs as $tab) {
                foreach ($languages as $language) {
                    $this->db->query("INSERT INTO " . DB_PREFIX . "product_tab_name (tab_id, language_id, name) VALUES (" . $tab['id'] . ", " . (int)$language['language_id'] . ", '" . $tab['name'] . "')");
                }
            }
        }
        $this->load->model('setting/setting');
        $this->model_setting_setting->editSetting('custom_product_tab', $this->defaults);
    }

    public function uninstall() {
        if ($this->config->get("cpt_remove_sql_changes")) {
            $this->db->query("DROP TABLE IF EXISTS " . DB_PREFIX . "product_tab");
            $this->db->query("DROP TABLE IF EXISTS " . DB_PREFIX . "product_tab_name");
            $this->db->query("DROP TABLE IF EXISTS " . DB_PREFIX . "product_tab_default");
            $this->db->query("DROP TABLE IF EXISTS " . DB_PREFIX . "product_tab_content");
        }
        $this->load->model('setting/setting');
        $this->model_setting_setting->deleteSetting('custom_product_tab');
    }

    public function add() {
        $this->language->load('module/custom_product_tab');

        $json = array();

        if (($this->request->server['REQUEST_METHOD'] == 'POST') && $this->validate() && $this->validateAdd($this->request->post)) {
            $name = $this->request->post['name'];
            $row = $this->request->post['row'];

            $this->load->model('module/custom_product_tab');
            $this->load->model('localisation/language');

            $languages = $this->model_localisation_language->getLanguages();

            $data = array(
                'sort_order' => 0,
                'status' => 0,
                'tab_name' => array(),
                'default' => array(),
            );

            foreach ($languages as $language) {
                $data['name'][$language['language_id']] = $name;
                $data['default'][$language['language_id']] = '';
            }

            $tab_id = $this->model_module_custom_product_tab->addTab($data);

            $json['success'] = 1;
            $json['tab_id'] = $tab_id;
        } else {
            $json['error'] = $this->language->get('error_add_tab');
        }

        $this->response->setOutput(json_encode($json));
    }

    public function remove() {
        $this->language->load('module/custom_product_tab');

        $json = array();

        if (($this->request->server['REQUEST_METHOD'] == 'POST') && $this->validate() && $this->validateRemove($this->request->post)) {
            $tab_id = $this->request->post['id'];

            $this->load->model('module/custom_product_tab');

            $this->model_module_custom_product_tab->deleteTab($tab_id);

            $json['success'] = 1;
        } else {
            $json['error'] = $this->language->get('error_remove_tab');
        }

        $this->response->setOutput(json_encode($json));
    }

    public function category() {
        $this->load->model('catalog/product');

        if (isset($this->request->get['category_id'])) {
            $category_id = $this->request->get['category_id'];
        } else {
            $category_id = 0;
        }

        $product_data = array();

        $results = $this->model_catalog_product->getProductsByCategoryId($category_id);

        foreach ($results as $result) {
            $product_data[] = array(
                'product_id' => $result['product_id'],
                'name'       => $result['name'],
                'model'      => $result['model']
            );
        }

        $this->response->setOutput(json_encode($product_data));
    }

    private function checkDatabaseStructure() {
        $error = array();

        $table_exists = $this->db->query("SHOW TABLES LIKE '" . DB_PREFIX . "product_tab'");
        if (!$table_exists->num_rows) {
            $error['warning'] = sprintf($this->language->get('error_missing_table'), DB_PREFIX . 'product_tab');
        }

        $table_exists = $this->db->query("SHOW TABLES LIKE '" . DB_PREFIX . "product_tab_name'");
        if (!$table_exists->num_rows) {
            $error['warning'] = sprintf($this->language->get('error_missing_table'), DB_PREFIX . 'product_tab_name');
        }

        $table_exists = $this->db->query("SHOW TABLES LIKE '" . DB_PREFIX . "product_tab_default'");
        if (!$table_exists->num_rows) {
            $error['warning'] = sprintf($this->language->get('error_missing_table'), DB_PREFIX . 'product_tab_default');
        }

        $table_exists = $this->db->query("SHOW TABLES LIKE '" . DB_PREFIX . "product_tab_content'");
        if (!$table_exists->num_rows) {
            $error['warning'] = sprintf($this->language->get('error_missing_table'), DB_PREFIX . 'product_tab_content');
        }

        if (!$error) {
            return true;
        } else {
            $this->error = array_merge($this->error, $error);
            return false;
        }
    }

    private function validate() {
        if (!$this->user->hasPermission('modify', 'module/custom_product_tab')) {
            $this->error['warning'] = $this->language->get('error_permission');
        }

        if (!$this->error) {
            return $this->checkDatabaseStructure();
        } else {
            return false;
        }
    }

    private function validateForm() {
        $tabs = (isset($this->request->post['tabs']) && is_array($this->request->post['tabs'])) ? $this->request->post['tabs'] : array();

        foreach ($tabs as $tab) {
            foreach ($tab["name"] as $language_id => $value) {
                if (!utf8_strlen($value)) {
                    $this->error['tab_name'][$tab['tab_id']][$language_id] = $this->language->get('error_tab_name');
                }
            }
        }

        if ($this->error && !isset($this->error['warning'])) {
            $this->error['warning'] = $this->language->get('error_warning');
        }

        if (!$this->error) {
            return $this->validate();
        } else {
            return false;
        }
    }

    private function validateAdd($post) {
        if (empty($post['name'])) {
            return false;
        }
        if (empty($post['row'])) {
            return false;
        }
        return true;
    }

    private function validateRemove($post) {
        if (empty($post['id'])) {
            return false;
        }
        return true;
    }
}
?>