<?php
/**
* 2007-2020 PrestaShop
*
* NOTICE OF LICENSE
*
* This source file is subject to the Open Software License (OSL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/osl-3.0.php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@buy-addons.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.prestashop.com for more information.
*
*  @author    Buy-Addons <contact@buy-addons.com>
*  @copyright 2007-2020 PrestaShop SA
*  @license   http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
*  International Registered Trademark & Property of PrestaShop SA
* @since 1.6
*/

class BASmartSeoAltTagsGeneral extends BASmartSeoAltTags
{
    public $sql_limit_product = 200;
    public function __construct()
    {
        parent::__construct();
    }
    public function updateObject($object)
    {
        $class = get_class($object);
        if ($class == 'Product') {
            $id = (int) $object->id;
            return $this->regenerateAltTag($id);
        }
        return false;
    }
    public function process($params = array())
    {
        $params;
        if (Tools::isSubmit("save") || Tools::isSubmit("saveandregenerate")) {
            $this->saveSettings();
        }
        return $this->createFormSetting();
    }

    public function createFormSetting()
    {
        // get data from configuration
        $selected_manufacturers = Configuration::get($this->name.'_manufacturers');
        $selected_suppliers = Configuration::get($this->name.'_suppliers');
        $selected_categories =json_decode(Configuration::get($this->name.'_categories'));
        $status = Configuration::get($this->name.'_status');
        $visibility = json_decode(Configuration::get($this->name.'_visibility'));
        $price = json_decode(Configuration::get($this->name.'_price'));
        $quantity = json_decode(Configuration::get($this->name.'_quantity'));
        $created_date = json_decode(Configuration::get($this->name.'_created_date'));
        $updated_date = json_decode(Configuration::get($this->name.'_updated_date'));
        $alt_format = json_decode(Configuration::get($this->name.'_alt_format'));

        $languages = Language::getLanguages(false);
        $id_default_l = (int) (Configuration::get('PS_LANG_DEFAULT'));
        $language_default = new Language($id_default_l);

        $this->smarty->assign('language_default', $language_default);

        $max_chars = (int) Configuration::get($this->name.'_max_chars');
        $alt_empty = (int) Configuration::get($this->name.'_alt_empty');
        $selected_languages = json_decode(Configuration::get($this->name.'_languages'));
        $this->smarty->assign('selected_manufacturers', json_decode($selected_manufacturers));
        $this->smarty->assign('selected_suppliers', json_decode($selected_suppliers));
        $this->smarty->assign('selected_languages', $selected_languages);
        $this->smarty->assign('status', $status);
        $this->smarty->assign('visibility', $visibility);
        $this->smarty->assign('price', $price);
        $this->smarty->assign('quantity', $quantity);
        $this->smarty->assign('created_date', $created_date);
        $this->smarty->assign('updated_date', $updated_date);
        $this->smarty->assign('alt_format', $alt_format);
        $this->smarty->assign('max_chars', $max_chars);
        $this->smarty->assign('alt_empty', $alt_empty);

        $manufacturers = $this->getManufacturers();
        $suppliers = $this->getSuppliers();
        $categories = $this->renderCategoryTree('categories', $selected_categories);
        $currency = Currency::getDefaultCurrency();

        $this->smarty->assign('currency', $currency);
        $this->smarty->assign('manufacturers', $manufacturers);
        $this->smarty->assign('suppliers', $suppliers);
        $this->smarty->assign('categories', $categories);
        $this->smarty->assign('languages', $languages);

        return $this->shortDisplay('views/templates/admin/general.tpl');
    }
    public function getManufacturers()
    {
        $db = Db::getInstance(_PS_USE_SQL_SLAVE_);
        $sql = 'SELECT * FROM ' . _DB_PREFIX_ . 'manufacturer';
        $manufacturers = $db->ExecuteS($sql);
        return $manufacturers;
    }
    public function getSuppliers()
    {
        $db = Db::getInstance(_PS_USE_SQL_SLAVE_);
        $sql = 'SELECT * FROM ' . _DB_PREFIX_ . 'supplier';
        $suppliers = $db->ExecuteS($sql);
        return $suppliers;
    }
    public function renderCategoryTree($name, $selectedCategories = array())
    {
        $root = Category::getRootCategory();
        $tree = new HelperTreeCategories('categories_col1');
        $tree->setUseCheckBox(false)
                ->setAttribute('is_category_filter', $root->id)
                ->setSelectedCategories((array)$selectedCategories)
                ->setRootCategory($root->id)
                ->setUseCheckBox(true)
                ->setInputName($name);
        $categories_tree = $this->tpl_list_vars['category_tree'] = $tree->render();
        return $categories_tree;
    }
    public function saveSettings()
    {
        $manufacturers = Tools::getValue("manufacturers");
        $manufacturers = json_encode($manufacturers);
        $suppliers = Tools::getValue("suppliers");
        $suppliers = json_encode($suppliers);
        $categories = Tools::getValue("categories");
        $categories = json_encode($categories);
        $visibility = Tools::getValue("visibility");
        $visibility = json_encode($visibility);
        $price = Tools::getValue("price");
        $price = json_encode($price);
        $quantity = Tools::getValue("quantity");
        $quantity = json_encode($quantity);
        $created_date = Tools::getValue("created_date");
        $created_date = json_encode($created_date);
        $updated_date = Tools::getValue("updated_date");
        $updated_date = json_encode($updated_date);
        $languages = Tools::getValue("languages");
        $languages = json_encode($languages);
        $alt_format = Tools::getValue("alt_format");

        $max_chars = Tools::getValue("max_chars");
        if (!empty($max_chars)) {
            $is_int = Validate::isInt($max_chars);
            if ($is_int == false) {
                $this->smarty->assign('error', $this->l('Max Chars is not valid. It is required as a number.'));
                return false;
            }
        }
        $status = (int) Tools::getValue("status");
        $alt_empty = (int) Tools::getValue("alt_empty");
        Configuration::updateValue($this->name.'_manufacturers', $manufacturers);
        Configuration::updateValue($this->name.'_suppliers', $suppliers);
        Configuration::updateValue($this->name.'_categories', $categories);
        Configuration::updateValue($this->name.'_status', $status);
        Configuration::updateValue($this->name.'_visibility', $visibility);
        Configuration::updateValue($this->name.'_price', $price);
        Configuration::updateValue($this->name.'_quantity', $quantity);
        Configuration::updateValue($this->name.'_created_date', $created_date);
        Configuration::updateValue($this->name.'_updated_date', $updated_date);
        Configuration::updateValue($this->name.'_alt_format', json_encode($alt_format));
        Configuration::updateValue($this->name.'_max_chars', $max_chars);
        Configuration::updateValue($this->name.'_languages', $languages);
        Configuration::updateValue($this->name.'_alt_empty', $alt_empty);
        $this->smarty->assign('success', $this->l('Successful update'));
        if (Tools::isSubmit("saveandregenerate")) {
            $this->regenerateALL();
        }
        return true;
    }
    public function regenerateALL()
    {
        Configuration::updateGlobalValue($this->name.'_regenerateALL', 1);
        $admin_token = Tools::getAdminTokenLite('AdminModules');
        $url = AdminController::$currentIndex.'&configure='.$this->name.'&batask=general&token='.$admin_token;
        Tools::redirectAdmin($url);
    }
    public function regenerateAltTag($id_product)
    {
        $id_shop = (int) Context::getContext()->shop->id;
        $id_product = (int) $id_product;

        $product = new Product($id_product, false, null, $id_shop);
        $retail_incl_tax = Product::getPriceStatic($id_product, true);
        $retail_incl_tax = Tools::displayPrice($retail_incl_tax);
        $wholesale_price = Tools::displayPrice($product->wholesale_price);
        $price = Tools::displayPrice($product->price);
        $unit_price = '';
        if ($product->unit_price_ratio > 0) {
            $unit_price = $product->price / $product->unit_price_ratio;
            $unit_price = Tools::displayPrice($unit_price);
        }
        $price_before_discount = Product::getPriceStatic($id_product, true, null, 6, null, false, false);
        $price_before_discount = Tools::displayPrice($price_before_discount);
        $price_after_discount = Product::getPriceStatic($id_product, true, null, 6, null, false, true);
        $price_after_discount = Tools::displayPrice($price_after_discount);
        
        $alt_formats = Configuration::get($this->name.'_alt_format');
        $alt_formats = json_decode($alt_formats, true);
        foreach ($alt_formats as &$alt_format) {
            $alt_format = str_replace('[id]', $product->id, $alt_format);
            $alt_format = str_replace('[reference]', $product->reference, $alt_format);
            $alt_format = str_replace('[ean13]', $product->ean13, $alt_format);
            $alt_format = str_replace('[upc]', $product->upc, $alt_format);
            $alt_format = str_replace('[brand]', $product->manufacturer_name, $alt_format);
            $alt_format = str_replace('[wholesale_excl_tax]', $wholesale_price, $alt_format);
            $alt_format = str_replace('[retail_excl_tax]', $price, $alt_format);
            $alt_format = str_replace('[retail_incl_tax]', $retail_incl_tax, $alt_format);
            $alt_format = str_replace('[unit_price]', $unit_price, $alt_format);
            $alt_format = str_replace('[unit]', $product->unity, $alt_format);
            $alt_format = str_replace('[price_before_discount]', $price_before_discount, $alt_format);
            $alt_format = str_replace('[price_after_discount]', $price_after_discount, $alt_format);
        }
        
        $images = $this->getImages($id_product);
        if (empty($images)) {
            return false;
        }
        //
        $languages = Language::getLanguages(false);
        $languages_l = array();
        foreach ($languages as $l) {
            $languages_l[$l['id_lang']] = $l['name'];
        }
        //
        $max_chars = (int) Configuration::get($this->name.'_max_chars');
        $db = Db::getInstance();
        $category = new Category($product->id_category_default);
        foreach ($images as $image) {
            $position = $image['position'];
            $id_image = (int) $image['id_image'];
            $id_lang = (int) $image['id_lang'];
            $name = $product->name[$id_lang];
            $meta_title = $product->meta_title[$id_lang];
            $meta_description = $product->meta_description[$id_lang];
            $friendly_url = $product->link_rewrite[$id_lang];
            $language = $languages_l[$id_lang];
            $alt_format_n = $alt_formats[$id_lang];
            $alt_format_n = str_replace('[name]', $name, $alt_format_n);
            $alt_format_n = str_replace('[id_image]', $id_image, $alt_format_n);
            $alt_format_n = str_replace('[position]', $position, $alt_format_n);
            $alt_format_n = str_replace('[meta_title]', $meta_title, $alt_format_n);
            $alt_format_n = str_replace('[meta_description]', $meta_description, $alt_format_n);
            $alt_format_n = str_replace('[friendly_url]', $friendly_url, $alt_format_n);
            $alt_format_n = str_replace('[language]', $language, $alt_format_n);
            $alt_format_n = str_replace('[main_category_name]', $category->name[$id_lang], $alt_format_n);
            
            if ($max_chars > 0) {
                $alt_format_n = Tools::substr($alt_format_n, 0, $max_chars);
            }
            if (!empty($alt_format_n)) {
                $sql = "UPDATE "._DB_PREFIX_."image_lang SET legend = '".pSQL($alt_format_n)."'";
                $sql .= " WHERE id_image = ".$id_image;
                $sql .= " AND id_lang = ".$id_lang;
                $db->query($sql);
            }
        }
        return true;
    }
    public function getImages($id_product)
    {
        $db = Db::getInstance();
        $sql = "SELECT i.id_image, i.position, il.id_lang";
        $sql .= " FROM "._DB_PREFIX_."image AS i";
        $sql .= " LEFT JOIN "._DB_PREFIX_."image_shop AS ishop";
        $sql .= " ON (i.id_image = ishop.id_image AND i.id_product = ishop.id_product)";
        $sql .= " LEFT JOIN "._DB_PREFIX_."image_lang AS il ON i.id_image = il.id_image";

        $id_shop = (int) Context::getContext()->shop->id;
        $where = array("ishop.id_shop = ".(int) $id_shop);
        $where[] = "i.id_product = ".(int) $id_product;
        $alt_empty = (int) Configuration::get($this->name.'_alt_empty');
        if ($alt_empty == 1) {
            $where[] = "(il.legend = '' OR il.legend IS NULL)";
        }
        $languages = json_decode(Configuration::get($this->name.'_languages'));
        if (!empty($languages)) {
            $languages = array_map('intval', $languages);
            $where[] = 'il.id_lang IN ('.implode(',', $languages).')';
        }
        $sql .= ' WHERE '. implode(' AND ', $where);
        return $db->ExecuteS($sql);
    }
    public function findProducts($from = 0)
    {
        $db = Db::getInstance(_PS_USE_SQL_SLAVE_);
        $sql = 'SELECT DISTINCT p.id_product, p.* FROM ' . _DB_PREFIX_ . 'product AS p';
        $sql .= ' INNER JOIN ' . _DB_PREFIX_ . 'product_shop AS ps ON p.id_product = ps.id_product';
        $sql .= ' LEFT JOIN ' . _DB_PREFIX_ . 'product_supplier AS psup ON p.id_product = psup.id_product';
        $sql .= ' LEFT JOIN ' . _DB_PREFIX_ . 'category_product AS cp ON p.id_product = cp.id_product';
        $sql .= ' LEFT JOIN ' . _DB_PREFIX_ . 'stock_available AS sa ON p.id_product = sa.id_product';

        $id_shop = (int) Context::getContext()->shop->id;
        $where = array("ps.id_shop = ".$id_shop);
        //
        $manufacturers = json_decode(Configuration::get($this->name.'_manufacturers'));
        if (!empty($manufacturers)) {
            $manufacturers = array_map('intval', $manufacturers);
            $where[] = 'p.id_manufacturer IN ('.implode(',', $manufacturers).')';
        }
        //
        $suppliers = json_decode(Configuration::get($this->name.'_suppliers'));
        if (!empty($suppliers)) {
            $suppliers = array_map('intval', $suppliers);
            $where[] = 'psup.id_supplier IN ('.implode(',', $suppliers).')';
        }
        //
        $categories = json_decode(Configuration::get($this->name.'_categories'));
        if (!empty($categories)) {
            $categories = array_map('intval', $categories);
            $where[] = 'cp.id_category IN ('.implode(',', $categories).')';
        }
        //
        $status = (int) Configuration::get($this->name.'_status');
        if ($status == 1) {
            $where[] = 'ps.active = 1';
        } elseif ($status == 2) {
            $where[] = 'ps.active = 0';
        }
        //
        $visibility = json_decode(Configuration::get($this->name.'_visibility'));
        if (!empty($visibility)) {
            $visibility = array_map('pSQL', $visibility);
            $where[] = "ps.visibility IN ('".implode("','", $visibility)."')";
        }
        //
        $price = (array) json_decode(Configuration::get($this->name.'_price'));
        if (isset($price['from']) && $price['from']>0) {
            $where[] = "ps.price >=".(float) $price['from'];
        }
        if (isset($price['to']) && $price['to'] > 0) {
            $where[] = "ps.price <=".(float) $price['to'];
        }
        //
        $quantity = (array) json_decode(Configuration::get($this->name.'_quantity'));
        if (isset($quantity['from']) && $quantity['from'] > 0) {
            $where[] = "sa.id_product_attribute = 0 AND sa.quantity >=".(int) $quantity['from'];
        }
        if (isset($quantity['to']) && $quantity['to'] > 0) {
            $where[] = "sa.id_product_attribute = 0 AND sa.quantity <=".(int) $quantity['to'];
        }
        //
        $created_date = (array) json_decode(Configuration::get($this->name.'_created_date'));
        if (!empty($created_date['from'])) {
            $c_from = str_replace('/', '-', $created_date['from']);
            $c_from = str_replace('.', '-', $c_from);
            $c_from = date("Y-m-d", strtotime($c_from)) . " 00:00:00";
            $where[] = "ps.date_add >='".pSQL($c_from)."'";
        }
        if (!empty($created_date['to'])) {
            $c_to = str_replace('/', '-', $created_date['to']);
            $c_to = str_replace('.', '-', $c_to);
            $c_to = date("Y-m-d", strtotime($c_to)) . " 23:59:59";
            $where[] = "ps.date_add <='".pSQL($c_to)."'";
        }
        //
        $updated_date = (array)  json_decode(Configuration::get($this->name.'_updated_date'));
        if (!empty($updated_date['from'])) {
            $u_from = str_replace('/', '-', $updated_date['from']);
            $u_from = str_replace('.', '-', $u_from);
            $u_from = date("Y-m-d", strtotime($u_from)) . " 00:00:00";
            $where[] = "ps.date_upd >='".pSQL($u_from)."'";
        }
        if (!empty($updated_date['to'])) {
            $u_to = str_replace('/', '-', $updated_date['to']);
            $u_to = str_replace('.', '-', $u_to);
            $u_to = date("Y-m-d", strtotime($u_to)) . " 23:59:59";
            $where[] = "ps.date_upd <='".pSQL($u_to)."'";
        }
        $sql .= ' WHERE '. implode(' AND ', $where);
        $sql .= ' LIMIT '. (int) $from. ', '. $this->sql_limit_product;
        $products = $db->ExecuteS($sql);
        return $products;
    }
    public function installNew()
    {
        $shopList = Shop::getShops(false);
        $shopList[] = array(
            'id_shop' => null,
            'id_shop_group' => null,
        );
        $languages = Language::getLanguages(false);
        $languages_l = array();
        $_languages = array();
        foreach ($languages as $l) {
            $languages_l[$l['id_lang']] = '[name] - [position]';
            $_languages[] = $l['id_lang'];
        }
        $alt_format = json_encode($languages_l);
        $_languages = json_encode($_languages);
        foreach ($shopList as $shop) {
            $id_shop = (int) $shop['id_shop'];
            Configuration::updateValue($this->name.'_max_chars', 128, false, null, $id_shop);
            Configuration::updateValue($this->name.'_status', 0, false, null, $id_shop);
            $v = '["both","search","catalog","none"]';
            Configuration::updateValue($this->name.'_visibility', $v, false, null, $id_shop);
            
            Configuration::updateValue($this->name.'_alt_empty', '1', false, null, $id_shop);
            $arr = json_encode(array("from"=>'', "to" =>''));
            Configuration::updateValue($this->name.'_price', $arr);
            Configuration::updateValue($this->name.'_quantity', $arr);
            Configuration::updateValue($this->name.'_created_date', $arr);
            Configuration::updateValue($this->name.'_updated_date', $arr);
            Configuration::updateValue($this->name.'_alt_format', $alt_format, false, null, $id_shop);
            Configuration::updateValue($this->name.'_languages', $_languages, false, null, $id_shop);
        }
        return true;
    }
    public static function uninstallNew()
    {
        return true;
    }
}
