* @copyright 2007-2019 PrestaShop SA * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) * International Registered Trademark & Property of PrestaShop SA */ if (!defined('_PS_VERSION_')) { exit; } function loadClass($class) { if (strpos($class, 'StFacetedSearch') !== false) { $file_name = substr($class, strpos($class, 'StFacetedSearch')+16); $file = __DIR__.'/src/'.str_replace('\\', '/', $file_name).'.php'; if (file_exists($file)) { require($file); } } } spl_autoload_register('loadClass'); use PrestaShop\Module\StFacetedSearch\Filters\Converter; use PrestaShop\Module\StFacetedSearch\HookDispatcher; use PrestaShop\PrestaShop\Core\Module\WidgetInterface; class StFacetedsearch extends Module implements WidgetInterface { protected static $access_rights = 0775; const LOCK_TOO_MANY_PRODUCTS = 5000; const LOCK_TEMPLATE_CREATION = 20000; const ISO_CODE_TAX_FREE = ['US',]; const DECIMAL_DIGITS = 5; private $ajax; private $stSearchFullTree; private $database; private $hookDispatcher; public $pages = array(); public $fields_form; public $fields_value; public $validation_errors = array(); public $_prefix_st = 'ST_FAC_SEARCH_'; public static $textTransform = array( array('id' => 0, 'name' => 'none'), array('id' => 1, 'name' => 'uppercase'), array('id' => 2, 'name' => 'lowercase'), array('id' => 3, 'name' => 'capitalize'), ); public static $facetedSearchFilters = array(); private $_font_inherit = 'inherit'; public $_html = ''; private $systemFonts = array("Helvetica","Arial","Verdana","Georgia","Tahoma","Times New Roman","sans-serif","IRANSans","IRANSansF","Vazir","VazirF"); private $googleFonts; public function __construct() { $this->name = 'stfacetedsearch'; $this->tab = 'front_office_features'; $this->version = '1.1.8'; $this->author = 'sunnytoo.com'; $this->need_instance = 0; $this->bootstrap = true; // $this->ajax = (bool) Tools::getValue('ajax'); parent::__construct(); $this->displayName = $this->l('Easy filter module'); $this->description = $this->l('Displays a block allowing multiple filters.'); $this->stSearchFullTree = Configuration::get($this->_prefix_st.'FULL_TREE'); $this->ps_versions_compliancy = ['min' => '1.7.1.0', 'max' => _PS_VERSION_]; $this->hookDispatcher = new HookDispatcher($this); $this->pages = array( 'category' => array( 'label'=>$this->l('Category pages, you need to select at least one category on the category tree below.'), 'id' => 'category', 'value' => 'category', ), 'newproducts' => array( 'label'=>$this->l('New products page'), 'id' => 'newproducts', 'value' => 'newproducts', ), 'bestsales' => array( 'label'=>$this->l('Best sales page'), 'id' => 'bestsales', 'value' => 'bestsales', ), 'pricesdrop' => array( 'label'=>$this->l('Prices drop page'), 'id' => 'pricesdrop', 'value' => 'pricesdrop', ), 'manufacturer' => array( 'label'=>$this->l('Manufacturer pages, you need to select at least one manufacturer on the list below.'), 'id' => 'manufacturer', 'value' => 'manufacturer', ), 'supplier' => array( 'label'=>$this->l('Supplier pages'), 'id' => 'supplier', 'value' => 'supplier', ), ); $this->googleFonts = include(dirname(__FILE__).'/googlefonts.php'); } /** * Check if method is an ajax request. * This check is an old behavior and only check for _GET value. * * @return bool */ public function isAjax() { return (bool) $this->ajax; } /** * Return the current database instance * * @return Db */ public function getDatabase() { if ($this->database === null) { $this->database = Db::getInstance(); } return $this->database; } /** * Return current context * * @return Context */ public function getContext() { return $this->context; } protected function getDefaultFilters() { return [ 'layered_selection_subcategories' => [ 'label' => 'Sub-categories filter', 'leixin' => 'subcategories', ], 'layered_selection_stock' => [ 'label' => 'Product stock filter', 'leixin' => 'stock', ], 'layered_selection_condition' => [ 'label' => 'Product condition filter', 'leixin' => 'condition', /*'key' => 'id', 'v_k' => 'name', 'item_k' => 0, 'children' => array( array( 'id'=>0, 'name'=>'New', ), array( 'id'=>1, 'name'=>'Used', ), array( 'id'=>2, 'name'=>'Refurbished', ), ),*/ ], 'layered_selection_manufacturer' => [ 'label' => 'Product brand filter', 'leixin' => 'manufacturer', ], 'layered_selection_weight_slider' => [ 'label' => 'Product weight filter (slider)', 'leixin' => 'weight_slider', 'slider' => true, ], 'layered_selection_price_slider' => [ 'label' => 'Product price filter (slider)', 'leixin' => 'price_slider', 'slider' => true, ], ]; } public function install() { $installed = parent::install() && $this->registerHook($this->getHookDispatcher()->getAvailableHooks()); // Installation failed (or hook registration) => uninstall the module if (!$installed) { $this->uninstall(); return false; } if ($id_hook = Hook::getIdByName('productSearchProvider')) $this->updatePosition($id_hook, 0, 1); foreach ($this->getFormFieldsDefault() as $k => $v) { Configuration::updateValue($this->_prefix_st.Tools::strtoupper($k), $v); } $this->stSearchFullTree = 1; if (!$this->rebuildLayeredStructure()) { return false; } $this->buildLayeredCategories(); $productsCount = $this->getDatabase()->getValue('SELECT COUNT(*) FROM `' . _DB_PREFIX_ . 'product`'); /*if ($productsCount < static::LOCK_TEMPLATE_CREATION) { $this->rebuildLayeredCache(); }*/ $this->rebuildPriceIndexTable(); $this->installIndexableAttributeTable(); $this->installProductAttributeTable(); $this->installFacetItemTable(); if ($productsCount < static::LOCK_TOO_MANY_PRODUCTS) { $this->fullPricesIndexProcess(); $this->indexAttributes(); } $this->updatePosition(Hook::getIdByName('displayLeftColumn'), 0, 1); // Configuration::updateValue($this->_prefix_st.'FILTERS_PER_XL', 3); Configuration::updateValue($this->_prefix_st.'FILTERS_PER_LG', 3); Configuration::updateValue($this->_prefix_st.'FILTERS_PER_MD', 2); Configuration::updateValue($this->_prefix_st.'HEADING_PADDINGS_P_L', 8); Configuration::updateValue($this->_prefix_st.'HEADING_PADDINGS_P_T', 10); Configuration::updateValue($this->_prefix_st.'HEADING_PADDINGS_P_R', 8); Configuration::updateValue($this->_prefix_st.'HEADING_PADDINGS_P_B', 10); Configuration::updateValue($this->_prefix_st.'BLOCK_PADDINGS_P_L', 0); Configuration::updateValue($this->_prefix_st.'BLOCK_PADDINGS_P_T', 0); Configuration::updateValue($this->_prefix_st.'BLOCK_PADDINGS_P_R', 0); Configuration::updateValue($this->_prefix_st.'BLOCK_PADDINGS_P_B', 0); Configuration::updateValue($this->_prefix_st.'FILTER_PADDINGS_P_L', 10); Configuration::updateValue($this->_prefix_st.'FILTER_PADDINGS_P_T', 10); Configuration::updateValue($this->_prefix_st.'FILTER_PADDINGS_P_R', 10); Configuration::updateValue($this->_prefix_st.'FILTER_PADDINGS_P_B', 10); Configuration::updateValue($this->_prefix_st.'FILTER_TITLE_PADDINGS_P_L', 10); Configuration::updateValue($this->_prefix_st.'FILTER_TITLE_PADDINGS_P_T', 8); Configuration::updateValue($this->_prefix_st.'FILTER_TITLE_PADDINGS_P_R', 10); Configuration::updateValue($this->_prefix_st.'FILTER_TITLE_PADDINGS_P_B', 8); Configuration::updateValue($this->_prefix_st.'FILTER_TITLE_BORDER_SIZES_B_L', 0); Configuration::updateValue($this->_prefix_st.'FILTER_TITLE_BORDER_SIZES_B_T', 0); Configuration::updateValue($this->_prefix_st.'FILTER_TITLE_BORDER_SIZES_B_R', 0); Configuration::updateValue($this->_prefix_st.'FILTER_TITLE_BORDER_SIZES_B_B', 1); Configuration::updateValue($this->_prefix_st.'FILTER_BORDER_SIZES_B_L', 0); Configuration::updateValue($this->_prefix_st.'FILTER_BORDER_SIZES_B_T', 0); Configuration::updateValue($this->_prefix_st.'FILTER_BORDER_SIZES_B_R', 0); Configuration::updateValue($this->_prefix_st.'FILTER_BORDER_SIZES_B_B', 0); /*Configuration::updateValue($this->_prefix_st.'BUTTON_PADDINGS_P_L', 0); Configuration::updateValue($this->_prefix_st.'BUTTON_PADDINGS_P_T', 0); Configuration::updateValue($this->_prefix_st.'BUTTON_PADDINGS_P_R', 0); Configuration::updateValue($this->_prefix_st.'BUTTON_PADDINGS_P_B', 0);*/ Configuration::updateValue($this->_prefix_st.'ACTIVE_PADDINGS_P_L', 10); Configuration::updateValue($this->_prefix_st.'ACTIVE_PADDINGS_P_T', 10); Configuration::updateValue($this->_prefix_st.'ACTIVE_PADDINGS_P_R', 10); Configuration::updateValue($this->_prefix_st.'ACTIVE_PADDINGS_P_B', 10); Configuration::updateValue($this->_prefix_st.'FONT_TEXT', ''); Configuration::updateValue($this->_prefix_st.'FONT_FILTER_TITLE', ''); Configuration::updateValue('STSN_FILTER_POSITION', 0); // Disable old module. $inst = Module::getInstanceByName('ps_facetedsearch'); $inst->disable(); return true; } public function uninstall() { /* Delete all configurations */ Configuration::deleteByName($this->_prefix_st.'SHOW_QTIES'); Configuration::deleteByName($this->_prefix_st.'FULL_TREE'); Configuration::deleteByName($this->_prefix_st.'INDEXED'); Configuration::deleteByName($this->_prefix_st.'PRICE_USETAX'); Configuration::deleteByName($this->_prefix_st.'CATEGORY_DEPTH'); Configuration::deleteByName($this->_prefix_st.'PRICE_ROUNDING'); Configuration::deleteByName($this->_prefix_st.'BY_DEFAULT_CATEGORY'); Configuration::deleteByName($this->_prefix_st.'SHOW_ATTRIBUTE_IMAGE'); Configuration::deleteByName($this->_prefix_st.'COMPATIBILITY_MODE'); $this->getDatabase()->execute('DROP TABLE IF EXISTS ' . _DB_PREFIX_ . 'st_search_category'); $this->getDatabase()->execute('DROP TABLE IF EXISTS ' . _DB_PREFIX_ . 'st_search_filter'); $this->getDatabase()->execute('DROP TABLE IF EXISTS ' . _DB_PREFIX_ . 'st_search_filter_block'); $this->getDatabase()->execute('DROP TABLE IF EXISTS ' . _DB_PREFIX_ . 'st_search_filter_shop'); $this->getDatabase()->execute('DROP TABLE IF EXISTS ' . _DB_PREFIX_ . 'st_search_indexable_attribute_group'); $this->getDatabase()->execute('DROP TABLE IF EXISTS ' . _DB_PREFIX_ . 'st_search_indexable_attribute_group_lang_value'); $this->getDatabase()->execute('DROP TABLE IF EXISTS ' . _DB_PREFIX_ . 'st_search_indexable_attribute_lang_value'); $this->getDatabase()->execute('DROP TABLE IF EXISTS ' . _DB_PREFIX_ . 'st_search_indexable_feature'); $this->getDatabase()->execute('DROP TABLE IF EXISTS ' . _DB_PREFIX_ . 'st_search_indexable_feature_lang_value'); $this->getDatabase()->execute('DROP TABLE IF EXISTS ' . _DB_PREFIX_ . 'st_search_indexable_feature_value_lang_value'); $this->getDatabase()->execute('DROP TABLE IF EXISTS ' . _DB_PREFIX_ . 'st_search_price_index'); $this->getDatabase()->execute('DROP TABLE IF EXISTS ' . _DB_PREFIX_ . 'st_search_product_attribute'); $this->getDatabase()->execute('DROP TABLE IF EXISTS ' . _DB_PREFIX_ . 'st_search_facet_af'); $this->getDatabase()->execute('DROP TABLE IF EXISTS ' . _DB_PREFIX_ . 'st_search_facet_item'); return parent::uninstall(); } /** * @return HookDispatcher */ public function getHookDispatcher() { return $this->hookDispatcher; } /* * Generate data product attributes * * @param int $idProduct * * @return boolean */ public function indexAttributes($idProduct = null) { if (null === $idProduct) { $this->getDatabase()->execute('TRUNCATE ' . _DB_PREFIX_ . 'st_search_product_attribute'); } else { $this->getDatabase()->execute( 'DELETE FROM ' . _DB_PREFIX_ . 'st_search_product_attribute WHERE id_product = ' . (int) $idProduct ); } return $this->getDatabase()->execute( 'INSERT INTO `' . _DB_PREFIX_ . 'st_search_product_attribute` (`id_attribute`, `id_product`, `id_attribute_group`, `id_shop`) SELECT pac.id_attribute, pa.id_product, ag.id_attribute_group, product_attribute_shop.`id_shop` FROM ' . _DB_PREFIX_ . 'product_attribute pa' . Shop::addSqlAssociation('product_attribute', 'pa') . ' INNER JOIN ' . _DB_PREFIX_ . 'product_attribute_combination pac ON pac.id_product_attribute = pa.id_product_attribute INNER JOIN ' . _DB_PREFIX_ . 'attribute a ON (a.id_attribute = pac.id_attribute) INNER JOIN ' . _DB_PREFIX_ . 'attribute_group ag ON ag.id_attribute_group = a.id_attribute_group ' . ($idProduct === null ? '' : 'AND pa.id_product = ' . (int) $idProduct) . ' GROUP BY a.id_attribute, pa.id_product , product_attribute_shop.`id_shop`' ); } /* * Generate data for product features * * @return boolean */ public function indexFeatures() { return $this->getDatabase()->execute( 'INSERT INTO `' . _DB_PREFIX_ . 'st_search_indexable_feature` ' . 'SELECT id_feature, 1 FROM `' . _DB_PREFIX_ . 'feature` ' . 'WHERE id_feature NOT IN (SELECT id_feature FROM ' . '`' . _DB_PREFIX_ . 'st_search_indexable_feature`)' ); } /* * Generate data for product attribute group * * @return boolean */ public function indexAttributeGroup() { return $this->getDatabase()->execute( 'INSERT INTO `' . _DB_PREFIX_ . 'st_search_indexable_attribute_group` ' . 'SELECT id_attribute_group, 1 FROM `' . _DB_PREFIX_ . 'attribute_group` ' . 'WHERE id_attribute_group NOT IN (SELECT id_attribute_group FROM ' . '`' . _DB_PREFIX_ . 'st_search_indexable_attribute_group`)' ); } /** * Full prices index process * * @param int $cursor in order to restart indexing from the last state * @param bool $ajax */ public function fullPricesIndexProcess($cursor = 0, $ajax = false, $smart = false) { if ($cursor == 0) { $this->rebuildPriceIndexTable(); } return $this->indexPrices($cursor, true, $ajax, $smart); } /** * Prices index process * * @param int $cursor in order to restart indexing from the last state * @param bool $ajax */ public function pricesIndexProcess($cursor = 0, $ajax = false) { return $this->indexPrices($cursor, false, $ajax); } /** * Index product prices * * @param int $idProduct * @param bool $smart Delete before reindex */ public function indexProductPrices($idProduct, $smart = true) { static $groups = null; if ($groups === null) { $groups = $this->getDatabase()->executeS('SELECT id_group FROM `' . _DB_PREFIX_ . 'group_reduction`'); if (!$groups) { $groups = []; } } $shopList = Shop::getShops(false, null, true); foreach ($shopList as $idShop) { $currencyList = Currency::getCurrencies(false, 1, new Shop($idShop)); $minPrice = []; $maxPrice = []; if ($smart) { $this->getDatabase()->execute('DELETE FROM `' . _DB_PREFIX_ . 'st_search_price_index` WHERE `id_product` = ' . (int) $idProduct . ' AND `id_shop` = ' . (int) $idShop); } $taxRatesByCountry = $this->getDatabase()->executeS( 'SELECT t.rate rate, tr.id_country, c.iso_code ' . 'FROM `' . _DB_PREFIX_ . 'product_shop` p ' . 'LEFT JOIN `' . _DB_PREFIX_ . 'tax_rules_group` trg ON ' . '(trg.id_tax_rules_group = p.id_tax_rules_group AND p.id_shop = ' . (int) $idShop . ') ' . 'LEFT JOIN `' . _DB_PREFIX_ . 'tax_rule` tr ON (tr.id_tax_rules_group = trg.id_tax_rules_group) ' . 'LEFT JOIN `' . _DB_PREFIX_ . 'tax` t ON (t.id_tax = tr.id_tax AND t.active = 1) ' . 'JOIN `' . _DB_PREFIX_ . 'country` c ON (tr.id_country=c.id_country AND c.active = 1) ' . 'WHERE id_product = ' . (int) $idProduct . ' ' . 'GROUP BY id_product, tr.id_country' ); if (empty($taxRatesByCountry) || !Configuration::get('ST_FAC_SEARCH_PRICE_USETAX')) { $idCountry = (int) Configuration::get('PS_COUNTRY_DEFAULT'); $isoCode = Country::getIsoById($idCountry); $taxRatesByCountry = [['rate' => 0, 'id_country' => $idCountry, 'iso_code' => $isoCode]]; } $productMinPrices = $this->getDatabase()->executeS( 'SELECT id_shop, id_currency, id_country, id_group, from_quantity FROM `' . _DB_PREFIX_ . 'specific_price` WHERE id_product = ' . (int) $idProduct . ' AND id_shop IN (0,' . (int) $idShop . ')' ); // Get product attribute if "Separate products by attribute" module enabled $id_product_attributes = []; $has_attribtes = false; if (Module::isEnabled('stproductsbyattrs')) { $attributes = $this->getDatabase()->executeS('SELECT `id_product_attribute` FROM `' . _DB_PREFIX_ . 'product_attribute_shop` WHERE `id_product` = '.(int)$idProduct.' AND `id_shop` = '.(int)$idShop); foreach($attributes as $val) { $id_product_attributes[] = $val['id_product_attribute']; $has_attribtes = true; } unset($val); } if (!$id_product_attributes) { $id_product_attributes = [0]; } $countries = Country::getCountries($this->getContext()->language->id, true, false, false); foreach ($countries as $country) { $idCountry = $country['id_country']; foreach($id_product_attributes as $ipa) { // Get price by currency & country, without reduction! foreach ($currencyList as $currency) { /* quantity discount de shi hou, dao zhi mini_quantity de jia ge mei you ji shuan. if (!empty($productMinPrices)) { $minPrice[$idCountry][$currency['id_currency']] = null; $maxPrice[$idCountry][$currency['id_currency']] = null; continue; }*/ $price = Product::priceCalculation( $idShop, (int) $idProduct, $ipa ? $ipa : null, $idCountry, null, null, $currency['id_currency'], null, null, (bool)Configuration::get('ST_FAC_SEARCH_PRICE_USETAX'), 6, // Decimals false, false, true, $specificPriceOutput, true ); $minPrice[$ipa][$idCountry][$currency['id_currency']] = $price; $maxPrice[$ipa][$idCountry][$currency['id_currency']] = $price; } foreach ($productMinPrices as $specificPrice) { foreach ($currencyList as $currency) { if ($specificPrice['id_currency'] && $specificPrice['id_currency'] != $currency['id_currency'] ) { continue; } $price = Product::priceCalculation( $idShop, (int) $idProduct, $ipa ? $ipa : null, $idCountry, null, null, $currency['id_currency'], (($specificPrice['id_group'] == 0) ? null : $specificPrice['id_group']), $specificPrice['from_quantity'], (bool)Configuration::get('ST_FAC_SEARCH_PRICE_USETAX'), 6, false, true, true, $specificPriceOutput, true ); if ($price > $maxPrice[$ipa][$idCountry][$currency['id_currency']]) { $maxPrice[$ipa][$idCountry][$currency['id_currency']] = $price; } if ($price == 0) { continue; } if (null === $minPrice[$ipa][$idCountry][$currency['id_currency']] || $price < $minPrice[$ipa][$idCountry][$currency['id_currency']]) { $minPrice[$ipa][$idCountry][$currency['id_currency']] = $price; } } } foreach ($groups as $group) { foreach ($currencyList as $currency) { $price = Product::priceCalculation( $idShop, (int) $idProduct, $ipa ? $ipa : null, (int) $idCountry, null, null, (int) $currency['id_currency'], (int) $group['id_group'], null, (bool)Configuration::get('ST_FAC_SEARCH_PRICE_USETAX'), 6, false, true, true, $specificPriceOutput, true ); if (!isset($maxPrice[$ipa][$idCountry][$currency['id_currency']])) { $maxPrice[$ipa][$idCountry][$currency['id_currency']] = 0; } if (!isset($minPrice[$ipa][$idCountry][$currency['id_currency']])) { $minPrice[$ipa][$idCountry][$currency['id_currency']] = null; } if ($price == 0) { continue; } if (null === $minPrice[$ipa][$idCountry][$currency['id_currency']] || $price < $minPrice[$ipa][$idCountry][$currency['id_currency']]) { $minPrice[$ipa][$idCountry][$currency['id_currency']] = $price; } if ($price > $maxPrice[$ipa][$idCountry][$currency['id_currency']]) { $maxPrice[$ipa][$idCountry][$currency['id_currency']] = $price; } } } } } $values = []; // The taxes price was added alrady. /*foreach ($taxRatesByCountry as $taxRateByCountry) { $taxRate = $taxRateByCountry['rate']; $idCountry = $taxRateByCountry['id_country']; foreach($id_product_attributes as $ipa) { foreach ($currencyList as $currency) { $minPriceValue = array_key_exists($idCountry, $minPrice[$ipa]) ? $minPrice[$ipa][$idCountry][$currency['id_currency']] : 0; $maxPriceValue = array_key_exists($idCountry, $maxPrice[$ipa]) ? $maxPrice[$ipa][$idCountry][$currency['id_currency']] : 0; if (!in_array($taxRateByCountry['iso_code'], self::ISO_CODE_TAX_FREE)) { $minPriceValue = Tools::ps_round($minPriceValue * (100 + $taxRate) / 100, self::DECIMAL_DIGITS); $maxPriceValue = Tools::ps_round($maxPriceValue * (100 + $taxRate) / 100, self::DECIMAL_DIGITS); } $values[] = '(' . (int) $idProduct . ', ' . ($ipa ? $ipa . ',' : '') . ' ' . (int) $currency['id_currency'] . ', ' . $idShop . ', ' . $minPriceValue . ', ' . $maxPriceValue . ', ' . (int) $idCountry . ')'; // unset($minPrice[$idCountry], $maxPrice[$idCountry]);//why dao zhi zhi you mo ren di yige curriency, why unset? } } }*/ // Add price for all countreis foreach($maxPrice as $ipa1 => $value) { foreach($value as $id_country => $val) { foreach ($currencyList as $currency) { $values[] = '(' . (int) $idProduct . ', ' . ($ipa1 ? $ipa1 . ',' : '') . ' ' . (int) $currency['id_currency'] . ', ' . $idShop . ', ' . (isset($minPrice[$ipa1][$id_country]) ? $minPrice[$ipa1][$id_country][$currency['id_currency']] : 0) . ', ' . $val[$currency['id_currency']] . ', ' . (int)$id_country . ')'; } } } if (!empty($values)) { $this->getDatabase()->execute( 'INSERT INTO `' . _DB_PREFIX_ . 'st_search_price_index` (id_product, '.(Module::isEnabled('stproductsbyattrs') && $has_attribtes ? 'id_product_attribute,' : '').' id_currency, id_shop, price_min, price_max, id_country) VALUES ' . implode(',', $values) . ' ON DUPLICATE KEY UPDATE id_product = id_product' // Avoid duplicate keys ); } } } private function _checkImageDir() { $result = ''; if (!file_exists(_PS_UPLOAD_DIR_.$this->name)) { $success = @mkdir(_PS_UPLOAD_DIR_.$this->name, self::$access_rights, true) || @chmod(_PS_UPLOAD_DIR_.$this->name, self::$access_rights); if(!$success) $this->_html .= $this->displayError('"'._PS_UPLOAD_DIR_.$this->name.'" '.$this->l('An error occurred during new folder creation')); } if (!is_writable(_PS_UPLOAD_DIR_)) $this->_html .= $this->displayError('"'._PS_UPLOAD_DIR_.$this->name.'" '.$this->l('directory isn\'t writable.')); return $result; } /** * Get page content */ public function getContent() { // $this->installFacetItemTable();die; $check_result = $this->_checkImageDir(); $id_st_search_filter = (int)Tools::getValue('id_st_search_filter'); if(Tools::getValue('act')=='delete_image') { $result = array( 'r' => false, 'm' => '', 'd' => '' ); $id_st_search_facet_item = (int)Tools::getValue('id_st_search_facet_item'); if($id_st_search_facet_item) $result['r'] = $this->getDatabase()->execute('UPDATE `'._DB_PREFIX_.'st_search_facet_af` SET `img` = "" WHERE `id_st_search_facet_item`='.$id_st_search_facet_item.' AND `facet_item_value_k`='.Tools::getValue('facet_item_value_k')); die(json_encode($result)); } if (Tools::isSubmit('save'.$this->name) || Tools::isSubmit('save'.$this->name.'AndStay')) { $page = Tools::getValue('page', 'category'); $error = ''; /*if (!Tools::getValue('name')) { $error = $this->displayError($this->l('Filter template name required (cannot be empty)')); } else*/ if ($page == 'category' && !Tools::getValue('id_category')) { $error = $this->displayError($this->l('You must select at least one category.')); } else { $shopList = $assos = []; if (isset($_POST['checkBoxShopAsso_st_search_filter'])) { foreach ($_POST['checkBoxShopAsso_st_search_filter'] as $idShop => $row) { $assos[] = ['id_object' => (int) $id_st_search_filter, 'id_shop' => (int) $idShop]; $shopList[] = (int) $idShop; } } else { $assos[] = ['id_object' => (int) $id_st_search_filter, 'id_shop' => $this->getContext()->shop->id]; $shopList = [$this->getContext()->shop->id]; } $id_object = []; if ($page == 'category') { $id_object = Tools::getValue('id_category'); } elseif ($page == 'manufacturer') { foreach($_POST as $key => $val) { if (strpos($key, 'id_manufacturer_') !== false) { $id_object[] = substr($key, 16); } } if (!$id_object) { $error = $this->displayError($this->l('You must select at least one manufacturer.')); } } else { $id_object = [0]; } if (!$selected_filters = trim(Tools::getValue('enabled_filter_name'), ',')) { $error = $this->displayError($this->l('Please drag at least one filter under the "Filter blocks" tab.')); } if ($id_object && !$error) { if ($id_st_search_filter) { $this->getDatabase()->execute( 'DELETE FROM ' . _DB_PREFIX_ . 'st_search_filter WHERE id_st_search_filter = ' . (int) $id_st_search_filter ); //$this->buildLayeredCategories(); } $filterValues = []; if ($page == 'category') { $filterValues['categories'] = $id_object; } elseif ($page == 'manufacturer') { $filterValues['manufacturers'] = $id_object; } $filterValues['shop_list'] = $shopList; $facet_item = array(); $facet_index = 1; foreach (explode(',', $selected_filters) as $key) { $type = 0; $limit = 0; $zhuangtai = 1; if (Tools::getValue($key . '_filter_type')) { $type = Tools::getValue($key . '_filter_type'); } if (Tools::getValue($key . '_filter_show_limit')) { $limit = Tools::getValue($key . '_filter_show_limit'); } if (Tools::getValue($key . '_filter_zhuangtai')) { $zhuangtai = Tools::getValue($key . '_filter_zhuangtai'); } $filterValues[$key] = [ 'filter_type' => (int) $type, 'filter_show_limit' => (int) $limit, ]; $st = array( 'facet_type' => Tools::getValue($key.'_leixin'), 'facet_item_k' => Tools::getValue($key.'_item_k'), 'collapsed' => Tools::getValue($key.'_collapsed', 0), 'collapsed_mobile' => Tools::getValue($key.'_collapsed_mobile', 0), 'pips' => Tools::getValue($key.'_pips', 0), 'snap' => Tools::getValue($key.'_snap', 0), /*'numerical' => Tools::getValue($key.'_numerical', 0), 'numerical_step' => Tools::getValue($key.'_numerical_step', 0),*/ 'tooltips' => Tools::getValue($key.'_tooltips', 0), 'bar_bg_left' => Tools::getValue($key.'_bar_bg_left'), 'bar_bg_right' => Tools::getValue($key.'_bar_bg_right'), 'bg' => Tools::getValue($key.'_bg'), 'per_row' => Tools::getValue($key.'_per_row'), 'per_row_mobile' => Tools::getValue($key.'_per_row_mobile'), 'vertical' => Tools::getValue($key.'_vertical'), 'multi' => Tools::getValue($key.'_multi', 0), 'min_width' => Tools::getValue($key.'_min_width'), 'img_width' => Tools::getValue($key.'_img_width'), 'show_img' => Tools::getValue($key.'_show_img'), 'text_align' => Tools::getValue($key.'_text_align'), 'tb_mar' => Tools::getValue($key.'_tb_mar'), 'lr_mar' => Tools::getValue($key.'_lr_mar'), 'tb_pad' => Tools::getValue($key.'_tb_pad'), 'lr_pad' => Tools::getValue($key.'_lr_pad'), 'border' => Tools::getValue($key.'_border'), 'pad' => Tools::getValue($key.'_pad'), 'auto_sort' => Tools::getValue($key.'_auto_sort', 0), 'zhuangtai' => (int) $zhuangtai, 'position' => $facet_index++, ); $af_data = $this->getFacetAf($id_st_search_filter, $st['facet_type'], $st['facet_item_k']); $af_imgs = array(); if(is_array($af_data) || count($af_data)){ foreach ($af_data as $af_v) { if($af_v['img']) $af_imgs[$af_v['facet_item_value_k']] = array( 'img' => $af_v['img'], 'width' => $af_v['width'], 'height' => $af_v['height'], ); } } if(isset($_POST[$key.'_zhuangtai'])){ $af_index = 1; foreach ($_POST[$key.'_zhuangtai'] as $fk => $fv) { $jonny = array( 'facet_item_value_k' => $fk, 'zhuangtai' => $fv, 'position' => $af_index++, 'img' => '', 'width' => 0, 'height' => 0, ); if(isset($_FILES[$key.'_img']) && isset($_FILES[$key.'_img']['tmp_name'][$fk]) && !empty($_FILES[$key.'_img']['tmp_name'][$fk])){ $img_res = $this->stUploadImage($key.'_img', $fk); if(count($img_res['error'])){ // $error = array_merge($error,$img_res['error']); } elseif($img_res['image']) { $jonny['img'] = $img_res['image']; $jonny['width'] = $img_res['width']; $jonny['height'] = $img_res['height']; } }elseif(isset($af_imgs[$fk])){ $jonny = array_merge($jonny, $af_imgs[$fk]); } $st['af'][] = $jonny; } } $facet_item[] = $st; } /******* Extra settings begin. *****/ $filterValues['parameters'] = $params = []; $params['group_name'] = (int)Tools::getValue('group_name', 1); foreach($_POST as $key => $val) { if (strpos($key, 'title_') !== false) { $params['title'][str_replace('title_', '', $key)] = $val ? $val : $this->getDefaultTitle(); } } $filterValues['parameters'] = $params; unset($params); /******* Extra settings end. *****/ $valuesToInsert = [ 'name' => pSQL(Tools::getValue('name')), 'page' => pSQL($page), 'filters' => pSQL(serialize($filterValues)), 'n_categories' => (int)count($id_object), 'date_add' => date('Y-m-d H:i:s'), 'active' => (int)Tools::getvalue('active'), ]; if ($id_st_search_filter) { $valuesToInsert['id_st_search_filter'] = (int) $id_st_search_filter; } $idLayeredFilter = $id_st_search_filter ? (int) $id_st_search_filter : 'NULL'; $sql = 'INSERT INTO ' . _DB_PREFIX_ . 'st_search_filter (`id_st_search_filter`, `page`, `name`, `filters`, `n_categories`, `date_add`, `active`) VALUES ('.$idLayeredFilter.', "'.$valuesToInsert['page'].'", "' . pSQL($valuesToInsert['name']) . '", "' . $valuesToInsert['filters'] . '",' . (int) $valuesToInsert['n_categories'] . ',"' . pSQL($valuesToInsert['date_add']) . '",' . $valuesToInsert['active']. ')'; $this->getDatabase()->execute($sql); $idLayeredFilter = (int) $this->getDatabase()->Insert_ID(); if($idLayeredFilter){ $this->deleteFactedItem($idLayeredFilter); foreach ($facet_item as $item) { $af=array(); if(isset($item['af'])){ $af = $item['af']; unset($item['af']); } Db::getInstance()->insert('st_search_facet_item', array_merge(array( 'id_st_search_filter' => $idLayeredFilter, ), $item)); $id_st_search_facet_item = Db::getInstance()->Insert_ID(); if(count($af)){ foreach ($af as $afk=>$afv) { $af[$afk]['id_st_search_facet_item'] = $id_st_search_facet_item; } Db::getInstance()->insert('st_search_facet_af', $af); } } if (isset($assos)) { $this->getDatabase()->execute('DELETE FROM ' . _DB_PREFIX_ . 'st_search_filter_shop WHERE `id_st_search_filter` = ' . $idLayeredFilter); foreach ($assos as $asso) { $this->getDatabase()->execute( 'INSERT INTO ' . _DB_PREFIX_ . 'st_search_filter_shop (`id_st_search_filter`, `id_shop`) VALUES(' . $idLayeredFilter . ', ' . (int) $asso['id_shop'] . ')' ); } } } // Rebuild filter cache. $this->buildLayeredCategories(); // Init tab $this->_html .= $this->displayConfirmation($this->l('Your filter') . ' "' . Tools::safeOutput(Tools::getValue('name')) . '" ' . ($id_st_search_filter ? $this->l('was updated successfully.') : $this->l('was added successfully.'))); } } // Stay the edit page if error occurred. if ($error) { $this->_html .= $error; $_GET['add'.$this->name] = 1; } if(Tools::isSubmit('save'.$this->name.'AndStay') && isset($idLayeredFilter)){ Tools::redirectAdmin(AdminController::$currentIndex.'&configure='.$this->name.'&id_st_search_filter='.$idLayeredFilter.'&id_tab_index='.Tools::getValue('id_tab_index', 0).'&conf=4&update'.$this->name.'&token='.Tools::getAdminTokenLite('AdminModules')); } if (isset($_POST['id_tab_index']) && $_POST['id_tab_index']) $_POST['id_tab_index'] = 0; } elseif (Tools::isSubmit('save'.$this->name.'setting')) { $this->initConfigFormFields(); if (isset($_POST['custom_css']) && $_POST['custom_css']) { $_POST['custom_css'] = str_replace('\\', '¤', $_POST['custom_css']); } foreach ($this->fields_form as $form) { foreach ($form['form']['input'] as $field) { if (isset($field['validation'])) { $errors = array(); $value = Tools::getValue($field['name']); if (isset($field['required']) && $field['required'] && $value==false && (string)$value != '0') { $errors[] = sprintf($this->l('Field "%s" is required.'), $field['label']); } elseif ($value) { $field_validation = $field['validation']; if (!Validate::$field_validation($value)) { $errors[] = sprintf($this->l('Field "%s" is invalid.'), $field['label']); } } // Set default value if ($value === false && isset($field['default_value'])) { $value = $field['default_value']; } if ($field['name']=='limit' && $value>20) { $value=20; } if (count($errors)) { $this->validation_errors = array_merge($this->validation_errors, $errors); } elseif ($value==false) { switch ($field['validation']) { case 'isUnsignedId': case 'isUnsignedInt': case 'isInt': case 'isBool': $value = 0; break; case 'isNullOrUnsignedId': $value = $value==='0' || $value===0 ? '0' : ''; break; default: $value = ''; break; } Configuration::updateValue($this->_prefix_st.Tools::strtoupper($field['name']), $value); } else { Configuration::updateValue($this->_prefix_st.Tools::strtoupper($field['name']), $value); } } } } $this->updateCatePerRow(); $this->updateHeadingPaddings(); if (count($this->validation_errors)) { $this->_html .= $this->displayError(implode('
', $this->validation_errors)); } else { $this->_html .= $this->displayConfirmation($this->l('Settings saved successfully')); } $this->invalidateLayeredFilterBlockCache(); } elseif (Tools::isSubmit('delete'.$this->name)) { $layered_values = $this->getDatabase()->getValue( 'SELECT COUNT(0) FROM ' . _DB_PREFIX_ . 'st_search_filter WHERE id_st_search_filter = ' . (int)$id_st_search_filter ); // Init tab if ($layered_values) { $this->getDatabase()->execute( 'DELETE FROM ' . _DB_PREFIX_ . 'st_search_filter WHERE id_st_search_filter = ' . (int)$id_st_search_filter . ' LIMIT 1' ); $this->buildLayeredCategories(); $this->deleteFactedItem((int)$id_st_search_filter); $this->_html .= $this->displayConfirmation($this->l('Filter template was deleted.')); } else { $this->_html .= $this->displayError($this->l('Filter template not found')); } } elseif ((Tools::isSubmit('status'.$this->name))) { // Init tab if ($this->getDatabase()->execute('UPDATE `'._DB_PREFIX_.'st_search_filter` SET `active` = !active WHERE id_st_search_filter='.(int) Tools::getValue('id_st_search_filter'))) { $this->buildLayeredCategories(); $this->_html .= $this->displayConfirmation($this->l('Status updated.')); } } $moduleUrl = Tools::getProtocol(Tools::usingSecureMode()) . $_SERVER['HTTP_HOST'] . $this->getPathUri(); $this->context->controller->addJS($this->_path . 'views/dist/back.js'); $this->context->controller->addCSS($this->_path . 'views/dist/back.css'); $this->context->controller->addJS($this->_path . 'views/js/admin.js'); $this->context->controller->addCSS($this->_path . 'views/css/admin.css'); $this->_html .= ''; if (Tools::isSubmit('add'.$this->name) || (Tools::isSubmit('update'.$this->name) && $id_st_search_filter)) { $content = ''; $tabs = array( array('id' => '0', 'name' => $this->l('General settings')), array('id' => '1', 'name' => $this->l('Filter blocks')), ); $helper = $this->renderForm(); $this->getContext()->smarty->assign(array( 'token' => Tools::getAdminTokenLite('AdminModules'),//category tree daozhi token gaibian, daozhi ajax baochuo )); $content .= $helper->generateForm($this->fields_form); Media::addJsDef(array( 'id_tab_index' => (int)Tools::getValue('id_tab_index', 0), )); $this->smarty->assign(array( 'current_index' => AdminController::$currentIndex.'&configure='.$this->name.'&token='.Tools::getAdminTokenLite('AdminModules'), 'bo_tabs' => $tabs, 'bo_tab_content' => $content, )); return $this->_html . $this->display(__FILE__, 'views/templates/admin/bo_tab_layout.tpl'); } else { $content = ''; $tabs = array( array('id' => '0,2', 'name' => $this->l('General settings')), array('id' => '22,4,14,10,11,12,13,20,21,24', 'name' => $this->l('Style')), array('id' => '5,3', 'name' => $this->l('Range slider')), array('id' => '15,16,18,17,23', 'name' => $this->l('Button, checkbox, radio, ect.')), // array('id' => '6', 'name' => $this->l('Left column')), array('id' => '7', 'name' => $this->l('Center column')), array('id' => '8', 'name' => $this->l('Center column as dropdown lists')), array('id' => '9', 'name' => $this->l('Slide in sidebar')), array('id' => '19', 'name' => $this->l('Cron job')), ); $moduleUrl = Tools::getProtocol(Tools::usingSecureMode()) . $_SERVER['HTTP_HOST'] . $this->getPathUri(); // Indexation tab /*$this->smarty->assign(array( 'identi' => 1, 'panel_content' => $this->renderList(), )); $content .= $this->display(__FILE__, 'views/templates/admin/bo_panel_layout.tpl');*/ // Filter templates list tab $this->smarty->assign(array( 'identi' => 0, 'price_indexer_url' => $moduleUrl . 'stfacetedsearch-price-indexer.php' . '?token=' . substr(Tools::encrypt('stfacetedsearch/index'), 0, 10), 'full_price_indexer_url' => $moduleUrl . 'stfacetedsearch-price-indexer.php' . '?token=' . substr(Tools::encrypt('stfacetedsearch/index'), 0, 10) . '&full=1', 'attribute_indexer_url' => $moduleUrl . 'stfacetedsearch-attribute-indexer.php' . '?token=' . substr(Tools::encrypt('stfacetedsearch/index'), 0, 10), 'clear_cache_url' => $moduleUrl . 'stfacetedsearch-clear-cache.php' . '?token=' . substr(Tools::encrypt('stfacetedsearch/index'), 0, 10), 'id_lang' => $this->getContext()->cookie->id_lang, 'token' => substr(Tools::encrypt('stfacetedsearch/index'), 0, 10), 'base_folder' => urlencode(_PS_ADMIN_DIR_), )); $content .= $this->display(__FILE__, 'views/templates/admin/bo_indexation.tpl'); // Settings tab $content .= $this->renderConfigForm(); Media::addJsDef(array( 'id_tab_index' => (int)Tools::getValue('id_tab_index', 0), )); $this->smarty->assign(array( 'current_index' => AdminController::$currentIndex.'&configure='.$this->name.'&token='.Tools::getAdminTokenLite('AdminModules'), 'bo_tabs' => $tabs, 'bo_tab_content' => $content, )); return $this->_html .$this->renderList(). $this->display(__FILE__, 'views/templates/admin/bo_tab_layout.tpl'); } } protected function stUploadImage($key,$fk) { $result = array( 'error' => array(), 'image' => '', ); if (isset($_FILES[$key]) && isset($_FILES[$key]['tmp_name'][$fk]) && !empty($_FILES[$key]['tmp_name'][$fk])) { $type = strtolower(substr(strrchr($_FILES[$key]['name'][$fk], '.'), 1)); $name = str_replace(strrchr($_FILES[$key]['name'][$fk], '.'), '', $_FILES[$key]['name'][$fk]); $imagesize = array(); $imagesize = @getimagesize($_FILES[$key]['tmp_name'][$fk]); if (!empty($imagesize) && in_array(strtolower(substr(strrchr($imagesize['mime'], '/'), 1)), array('jpg', 'gif', 'jpeg', 'png')) && in_array($type, array('jpg', 'gif', 'jpeg', 'png'))) { $temp_name = tempnam(_PS_TMP_IMG_DIR_, 'PS'); /*$salt = $name ? Tools::str2url($name) : sha1(microtime()); $c_name = $salt;*/ $c_name = sha1(microtime()); /*if ($upload_error = ImageManager::validateUpload($_FILES[$key][$fk])) $result['error'][] = $upload_error; else*/ if (!$temp_name || !move_uploaded_file($_FILES[$key]['tmp_name'][$fk], $temp_name)) $result['error'][] = $this->getTranslator()->l('An error occurred during the image upload.'); else{ $infos = getimagesize($temp_name); if($type == 'gif' && !copy($temp_name, _PS_UPLOAD_DIR_.$this->name.'/'.$c_name.'.'.$type)) { $result['error'][] = $this->getTranslator()->l('An error occurred during the image upload.'); } elseif (!ImageManager::resize($temp_name, _PS_UPLOAD_DIR_.$this->name.'/'.$c_name.'.'.$type, null, null, $type)) { $result['error'][] = $this->getTranslator()->l('An error occurred during the image upload.'); } } if (isset($temp_name)) @unlink($temp_name); if(!count($result['error'])) { $result['image'] = $this->name.'/'.$c_name.'.'.$type; $result['width'] = $imagesize[0]; $result['height'] = $imagesize[1]; } return $result; } } else return $result; } public function updateCatePerRow() { $arr = $this->findCateProPer(); foreach ($arr as $key => $value) foreach ($value as $v) { $gv = Tools::getValue($v['id']); if ($gv!==false) Configuration::updateValue($this->_prefix_st.strtoupper($v['id']), $gv); } } public function updateHeadingPaddings() { $arr = $this->getMP(1); foreach ($arr as $mp) { $gv = Tools::getValue('heading_paddings_'.$mp['id']); if ($gv!==false) Configuration::updateValue($this->_prefix_st.strtoupper('HEADING_PADDINGS_'.$mp['id']), $gv); $gv = Tools::getValue('block_paddings_'.$mp['id']); if ($gv!==false) Configuration::updateValue($this->_prefix_st.strtoupper('BLOCK_PADDINGS_'.$mp['id']), $gv); $gv = Tools::getValue('filter_paddings_'.$mp['id']); if ($gv!==false) Configuration::updateValue($this->_prefix_st.strtoupper('FILTER_PADDINGS_'.$mp['id']), $gv); $gv = Tools::getValue('filter_title_paddings_'.$mp['id']); if ($gv!==false) Configuration::updateValue($this->_prefix_st.strtoupper('FILTER_TITLE_PADDINGS_'.$mp['id']), $gv); /*$gv = Tools::getValue('button_paddings_'.$mp['id']); if ($gv!==false) Configuration::updateValue($this->_prefix_st.strtoupper('BUTTON_PADDINGS_'.$mp['id']), $gv);*/ $gv = Tools::getValue('active_paddings_'.$mp['id']); if ($gv!==false) Configuration::updateValue($this->_prefix_st.strtoupper('ACTIVE_PADDINGS_'.$mp['id']), $gv); } $arr = $this->getMP(2); foreach ($arr as $mp) { $gv = Tools::getValue('filter_title_border_sizes_'.$mp['id']); if ($gv!==false) Configuration::updateValue($this->_prefix_st.strtoupper('FILTER_TITLE_BORDER_SIZES_'.$mp['id']), $gv); $gv = Tools::getValue('filter_border_sizes_'.$mp['id']); if ($gv!==false) Configuration::updateValue($this->_prefix_st.strtoupper('FILTER_BORDER_SIZES_'.$mp['id']), $gv); } } public function BuildInputs($group, $k) { $html = '
'; foreach($group AS $mp) { $html .= '
'. '
'; } return $html.'
'; } public function getMP($k=null){ $groups = array( 0 => array( array( 'id' => 'm_l', 'css_name' => 'margin-left', 'label' => $this->l('Left margin'), ), array( 'id' => 'm_t', 'css_name' => 'margin-top', 'label' => $this->l('Top margin'), ), array( 'id' => 'm_r', 'css_name' => 'margin-right', 'label' => $this->l('Right margin'), ), array( 'id' => 'm_b', 'css_name' => 'margin-bottom', 'label' => $this->l('Bottom margin'), ), ), 1 => array( array( 'id' => 'p_l', 'css_name' => 'padding-left', 'label' => $this->l('Left padding'), ), array( 'id' => 'p_t', 'css_name' => 'padding-top', 'label' => $this->l('Top padding'), ), array( 'id' => 'p_r', 'css_name' => 'padding-right', 'label' => $this->l('Right padding'), ), array( 'id' => 'p_b', 'css_name' => 'padding-bottom', 'label' => $this->l('Bottom padding'), ), ), 2 => array( array( 'id' => 'b_l', 'css_name' => 'border-left-width', 'label' => $this->l('Left border'), ), array( 'id' => 'b_t', 'css_name' => 'border-top-width', 'label' => $this->l('Top border'), ), array( 'id' => 'b_r', 'css_name' => 'border-right-width', 'label' => $this->l('Right border'), ), array( 'id' => 'b_b', 'css_name' => 'border-bottom-width', 'label' => $this->l('Bottom border'), ), ), ); return ($k!==null && isset($groups[$k])) ? $groups[$k] : $groups; } private function deleteFactedItem($idLayeredFilter){ $sql = new DbQuery(); $sql->select('`id_st_search_facet_item`') ->from('st_search_facet_item') ->where('`id_st_search_filter` = '.(int) $idLayeredFilter); $res = Db::getInstance()->executeS($sql); if(is_array($res) && count($res)){ $facet_items = array(); foreach ($res as $v) { $facet_items[] = $v['id_st_search_facet_item']; } Db::getInstance()->delete('st_search_facet_af', 'id_st_search_facet_item IN ('.implode(',', $facet_items).')'); } return Db::getInstance()->delete('st_search_facet_item', 'id_st_search_filter = ' . (int) $idLayeredFilter); } private function deleteFactedAf($id_st_search_facet_item){ return Db::getInstance()->delete('st_search_facet_af', 'id_st_search_facet_item = ' . (int) $id_st_search_facet_item); } public function getDefaultTitle() { // return $this->l('Filter By'); return ''; } public function fetchMediaServer($image) { $image = _THEME_PROD_PIC_DIR_.$image; return context::getContext()->link->protocol_content.Tools::getMediaServer($image).$image; } protected function renderList() { $fields_list = array( 'id_st_search_filter' => array( 'title' => $this->l('ID'), 'type' => 'text', 'search' => false, ), 'name' => array( 'title' => $this->l('Block name'), 'type' => 'text', 'search' => false, ), 'page' => array( 'title' => $this->l('Page'), 'type' => 'text', 'search' => false, 'class' => 'filter_page_name', ), 'active' => array( 'title' => $this->l('Status'), 'active' => 'status', 'type' => 'bool', 'search' => false, ), ); $helper = new HelperList(); $helper->shopLinkType = ''; $helper->simple_header = false; $helper->actions = array('edit', 'delete'); $helper->show_toolbar = true; $helper->toolbar_btn['new'] = array( 'href' => $this->context->link->getAdminLink('AdminModules').'&configure='.$this->name.'&module_name='.$this->name.'&add'.$this->name, 'desc' => $this->l('Add a filter group'), ); $helper->module = $this; $helper->identifier = 'id_st_search_filter'; $helper->title = $this->l('Filter groups'); $helper->table = $this->name; $helper->token = Tools::getAdminTokenLite('AdminModules'); $helper->currentIndex = AdminController::$currentIndex.'&configure='.$this->name; Shop::addTableAssociation('st_search_filter', array('type' => 'shop')); $list = $this->getDatabase()->executeS('SELECT * FROM `'._DB_PREFIX_.'st_search_filter` ssf '.Shop::addSqlAssociation('st_search_filter', 'ssf').' ORDER BY ssf.`date_add` DESC'); return $helper->generateList($list, $fields_list); } public function getFacetAf($id_st_search_filter, $type, $key){ return $this->getDatabase()->executeS( 'SELECT fa.* FROM ' . _DB_PREFIX_ . 'st_search_facet_af fa LEFT JOIN ' . _DB_PREFIX_ . 'st_search_facet_item fi ON (fa.id_st_search_facet_item = fi.id_st_search_facet_item) WHERE fi.id_st_search_filter = ' . (int) $id_st_search_filter . ' AND fi.facet_type="'.$type.'" AND fi.facet_item_k='.$key.' AND fa.position>0 ORDER BY fa.position' ); } public function renderForm() { $id_st_search_filter = (int)Tools::getValue('id_st_search_filter'); if($id_st_search_filter){ $exist = $this->getDatabase()->getValue( 'SELECT count(0) FROM `' . _DB_PREFIX_ . 'st_search_filter_shop` WHERE id_st_search_filter = ' . $id_st_search_filter.' AND id_shop='.$this->getContext()->shop->id ); if(!$exist) Tools::redirectAdmin(AdminController::$currentIndex.'&configure='.$this->name.'&token='.Tools::getAdminTokenLite('AdminModules')); } $template = $this->getDatabase()->getRow( 'SELECT * FROM `' . _DB_PREFIX_ . 'st_search_filter` WHERE id_st_search_filter = ' . $id_st_search_filter ); $filters = []; $filters['categories'] = $filters['shop_list'] = $filters['manufacturers'] = []; $template && $filters = Tools::unSerialize($template['filters']); $treeCategoriesHelper = new HelperTreeCategories('categories-treeview'); $treeCategoriesHelper ->setRootCategory(Shop::getContext() == Shop::CONTEXT_SHOP ? Category::getRootCategory()->id_category : 0) ->setInputName('id_category') ->setUseCheckBox(true) ->setSelectedCategories(isset($filters['categories']) ? $filters['categories'] : []) ; $selectShops = $selectBrands = []; foreach($filters['shop_list'] as $val) { $selectShops[$val] = $val; } if (isset($filters['manufacturers']) && $filters['manufacturers']) { foreach($filters['manufacturers'] as $val) { $selectBrands[] = $val; } } $params = $template && isset($filters['parameters']) ? $filters['parameters'] : []; unset($filters['categories'], $filters['shop_list'], $filters['manufacturers'], $filters['parameters']); $attributeGroups = $this->getDatabase()->executeS( 'SELECT ag.id_attribute_group, ag.is_color_group, agl.name, COUNT(DISTINCT(a.id_attribute)) n FROM ' . _DB_PREFIX_ . 'attribute_group ag '.Shop::addSqlAssociation('attribute_group', 'ag').' LEFT JOIN ' . _DB_PREFIX_ . 'attribute_group_lang agl ON (agl.id_attribute_group = ag.id_attribute_group) LEFT JOIN ' . _DB_PREFIX_ . 'attribute a ON (a.id_attribute_group = ag.id_attribute_group) WHERE agl.id_lang = ' . (int) $this->context->language->id . ' GROUP BY ag.id_attribute_group' ); $features = $this->getDatabase()->executeS( 'SELECT fl.`id_feature`, fl.`name`, COUNT(DISTINCT(fv.id_feature_value)) n FROM `' . _DB_PREFIX_ . 'feature` feat '.Shop::addSqlAssociation('feature', 'feat').' LEFT JOIN `' . _DB_PREFIX_ . 'feature_lang` fl ON (fl.`id_feature` = feat.`id_feature`) LEFT JOIN ' . _DB_PREFIX_ . 'feature_value fv ON (fv.`id_feature` = feat.`id_feature`) WHERE fl.`id_lang` = ' . (int) $this->context->language->id . ' GROUP BY fl.id_feature ORDER BY feat.`position`' ); if($id_st_search_filter){ foreach ($attributeGroups as $fk => $fv) { $feature_childern = $this->getDatabase()->executeS( 'SELECT al.name, a.id_attribute FROM ' . _DB_PREFIX_ . 'attribute a LEFT JOIN ' . _DB_PREFIX_ . 'attribute_lang al ON (a.id_attribute = al.id_attribute) WHERE al.id_lang = ' . (int) $this->context->language->id . ' AND a.id_attribute_group = '.$fv['id_attribute_group'].' GROUP BY al.`name` ORDER BY a.`id_attribute`' ); if(is_array($feature_childern)){ $attributeGroups[$fk]['n']=count($feature_childern); $children_linshi = $hebing = array(); foreach ($feature_childern as $l) { $children_linshi[$l['id_attribute']] = $l; } $st_search_facet_af = $this->getFacetAf($id_st_search_filter, 'ag', $fv['id_attribute_group']); foreach ($st_search_facet_af as $afv) { //img if($afv['img']) $afv['img'] = $this->fetchMediaServer($afv['img']); if(isset($children_linshi[$afv['facet_item_value_k']])){ $hebing[] = array_merge($children_linshi[$afv['facet_item_value_k']], $afv); unset($children_linshi[$afv['facet_item_value_k']]); } } $erji = array_merge($hebing, $children_linshi); $attributeGroups[$fk]['childern'] = $erji; }else{ $attributeGroups[$fk]['n']=0; } } foreach ($features as $fk => $fv) { $feature_childern = $this->getDatabase()->executeS( 'SELECT fvl.value, fv.id_feature_value FROM ' . _DB_PREFIX_ . 'feature_value fv LEFT JOIN ' . _DB_PREFIX_ . 'feature_value_lang fvl ON (fv.id_feature_value = fvl.id_feature_value) WHERE fvl.id_lang = ' . (int) $this->context->language->id . ' AND fv.id_feature = '.$fv['id_feature'].' GROUP BY fvl.`value` ORDER BY fv.`id_feature_value`' ); if(is_array($feature_childern)){ $features[$fk]['n']=count($feature_childern); $children_linshi = $hebing = array(); foreach ($feature_childern as $l) { $children_linshi[$l['id_feature_value']] = $l; } $st_search_facet_af = $this->getFacetAf($id_st_search_filter, 'feat', $fv['id_feature']); foreach ($st_search_facet_af as $afv) { if($afv['img']) $afv['img'] = $this->fetchMediaServer($afv['img']); if(isset($children_linshi[$afv['facet_item_value_k']])){ $hebing[] = array_merge($children_linshi[$afv['facet_item_value_k']], $afv); unset($children_linshi[$afv['facet_item_value_k']]); } } $erji = array_merge($hebing, $children_linshi); $features[$fk]['childern'] = $erji; }else{ $features[$fk]['n']=0; } } } $quanbu = $this->getDefaultFilters(); foreach ($attributeGroups as $v) { $v['label'] = sprintf($this->l('%s | Attribute | %d values'), $v['name'], $v['n']); $v['key'] = 'id_attribute'; $v['v_k'] = 'name'; $v['leixin'] = 'ag'; $v['item_k'] = $v['id_attribute_group']; $quanbu['layered_selection_ag_'.$v['id_attribute_group']] = $v; } foreach ($features as $v) { $v['label'] = sprintf($this->l('%s | Feature | %d values'), $v['name'], $v['n']); $v['key'] = 'id_feature_value'; $v['v_k'] = 'value'; $v['leixin'] = 'feat'; $v['item_k'] = $v['id_feature']; $quanbu['layered_selection_feat_'.$v['id_feature']] = $v; } $hebing = array(); foreach ($filters as $k => $v) { $facet_type = str_replace('layered_selection_', '', $k); $facet_item_k = 0; if(preg_match('/^(.*?)_(\d+)$/', $facet_type, $matchs)){ $facet_type = $matchs[1]; $facet_item_k = (int)$matchs[2]; } $facet_item = $this->getDatabase()->getRow( 'SELECT * FROM ' . _DB_PREFIX_ . 'st_search_facet_item WHERE id_st_search_filter = ' . (int) $id_st_search_filter . ' AND facet_type="'.$facet_type.'" '.($facet_item_k ? ' AND facet_item_k='.$facet_item_k : '') ); if($facet_item){ $v = array_merge($v,$facet_item); } $hebing[$k] = array_merge($v, $quanbu[$k]); unset($quanbu[$k]); } $this->context->smarty->assign([ // 'attribute_groups' => $attributeGroups, // 'features' => $features, 'quanbu' => array_merge($hebing, $quanbu), // 'filters' => $filters, 'total_filters' => count($quanbu), // 'total_filters' => 6 + count($attributeGroups) + count($features), // 'default_filters' => $default_filters, 'id_st_search_filter' => $id_st_search_filter, ]); $this->fields_form[0]['form'] = array( 'legend' => array( 'title' => $this->l('General settings'), 'icon' => 'icon-tags', ), 'input' => array( array( 'type' => 'color', 'label' => '', 'name' => 'bunengshanchu', 'class' => 'color', 'size' => 20, 'form_group_class' => 'hidden' ), array( 'type' => 'hidden', 'name' => 'id_tab_index', 'default_value' => 0, ), array( 'type' => 'text', 'label' => $this->l('Filter group name:'), 'name' => 'name', 'desc' => $this->l('Only as a reminder'), ), array( 'type' => 'text', 'label' => $this->l('Filter group title:'), 'name' => 'title', 'lang' => true, 'desc' => $this->l('This will show out on the front end, eg "Filter by". It can be empty.'), ), array( 'type' => 'radio', 'label' => $this->l('Apply to page:'), 'name' => 'page', 'default_value' => 'category', 'values' => $this->pages, 'validation' => 'isGenericName', 'form_group_class' => 'page-selector' ), array( 'label' => $this->l('Select categories for this filter group:'), 'type' => 'categories_select', 'category_tree' => $treeCategoriesHelper->render(), 'name' => 'id_category', 'form_group_class' => 'group-cate'.($id_st_search_filter && $template['page'] != 'category' ? ' hide' : ''), ), array( 'type' => 'checkbox', 'label' => $this->l('Manufacturers for this filter group:'), 'name' => 'id_manufacturer', 'values' => array( 'query' => $this->getManufacturers(), 'id' => 'id', 'name' => 'name', ), 'validation' => 'isUnsignedInt', 'form_group_class' => 'group-brand'.(!$id_st_search_filter || $id_st_search_filter && $template['page'] != 'manufacturer' ? ' hide' : ''), 'desc' => '
'.$this->l('Check All').''.$this->l('Uncheck All').'
', ), /*array( 'type' => 'switch', 'label' => $this->l('Show group name'), 'name' => 'group_name', 'is_bool' => true, 'default_value' => 1, 'values' => array( array( 'id' => 'group_name_on', 'value' => 1, 'label' => $this->l('Yes')), array( 'id' => 'group_name_off', 'value' => 0, 'label' => $this->l('No')), ), 'validation' => 'isUnsignedInt', ),*/ array( 'type' => 'switch', 'label' => $this->l('Status'), 'name' => 'active', 'is_bool' => true, 'default_value' => 1, 'values' => array( array( 'id' => 'active_on', 'value' => 1, 'label' => $this->l('Yes')), array( 'id' => 'active_off', 'value' => 0, 'label' => $this->l('No')), ), 'validation' => 'isBool', ), ), 'buttons' => array( array( 'type' => 'submit', 'title' => $this->l('Save'), 'icon' => 'process-icon-save', 'class'=> 'pull-right' ), ), 'submit' => array( 'title' => $this->l('Save and stay'), 'stay' => true ), ); $this->fields_form[1]['form'] = array( 'legend' => array( 'title' => $this->l('Filter blocks'), 'icon' => 'icon-tags', ), 'input' => array( array( 'type' => 'html', 'label' => $this->l('Filters'), 'hint' => $this->l('You can drag and drop filters to adjust position'), 'name' => $this->display(__FILE__, 'views/templates/admin/bo_filters.tpl'), 'form_group_class' => 'st_filter_list', ), ), 'buttons' => array( array( 'type' => 'submit', 'title' => $this->l('Save'), 'icon' => 'process-icon-save', 'class'=> 'pull-right' ), ), 'submit' => array( 'title' => $this->l('Save and stay'), 'stay' => true ), ); $fields_value = array( 'name' => $template ? $template['name'] : '', 'page' => $template ? $template['page'] : 'category', 'active' => $template ? $template['active'] : 1, // extra params 'group_name' => $template && isset($params['group_name']) ? $params['group_name'] : 1, 'title' => $template && isset($params['title']) ? $params['title'] : [], ); if (!$fields_value['title']) { foreach (Language::getLanguages(false) as $lang) { $fields_value['title'][$lang['id_lang']] = $this->getDefaultTitle(); } } foreach($selectBrands as $val) { $fields_value['id_manufacturer_'.$val] = 1; } if (Shop::isFeatureActive()) { $this->fields_form[0]['form']['input'][] = array( 'type' => 'shop', 'label' => $this->l('Shop association:'), 'name' => 'checkBoxShopAsso', ); $fields_value['shop'] = $selectShops; } foreach ($this->fields_form as $ffk => $ffv) { $this->fields_form[$ffk]['form']['input'][] = array( 'type' => 'go_back_to_list', 'label' => '', 'name' => AdminController::$currentIndex.'&configure='.$this->name.'&id_tab_index=0&token='.Tools::getValue('token'), ); } $helper = new HelperForm(); $helper->module = $this; $helper->show_toolbar = false; $helper->id = $id_st_search_filter; $helper->table = 'st_search_filter'; $helper->identifier = 'id_st_search_filter'; $lang = new Language((int)Configuration::get('PS_LANG_DEFAULT')); $helper->default_form_language = $lang->id; $helper->allow_employee_form_lang = Configuration::get('PS_BO_ALLOW_EMPLOYEE_FORM_LANG') ? Configuration::get('PS_BO_ALLOW_EMPLOYEE_FORM_LANG') : 0; $helper->submit_action = 'save'.$this->name; $helper->currentIndex = $this->context->link->getAdminLink('AdminModules', false).'&configure='.$this->name.'&tab_module='.$this->tab.'&module_name='.$this->name; $helper->token = Tools::getAdminTokenLite('AdminModules'); $fields_value['id_tab_index'] = 0; $fields_value['bunengshanchu'] = ''; $helper->tpl_vars = array( 'fields_value' => $fields_value, 'languages' => $this->context->controller->getLanguages(), 'id_language' => $this->context->language->id ); return $helper; } protected function renderConfigForm() { $this->initConfigFormFields(); $this->initDropListGroup(); $this->fields_form[11]['form']['input']['heading_paddings']['name'] = $this->BuildInputs($this->getMP(1), 'heading_paddings'); $this->fields_form[4]['form']['input']['block_paddings']['name'] = $this->BuildInputs($this->getMP(1), 'block_paddings'); $this->fields_form[13]['form']['input']['filter_title_paddings']['name'] = $this->BuildInputs($this->getMP(1), 'filter_title_paddings'); $this->fields_form[13]['form']['input']['filter_paddings']['name'] = $this->BuildInputs($this->getMP(1), 'filter_paddings'); // $this->fields_form[15]['form']['input']['button_paddings']['name'] = $this->BuildInputs($this->getMP(1), 'button_paddings'); $this->fields_form[12]['form']['input']['active_paddings']['name'] = $this->BuildInputs($this->getMP(1), 'active_paddings'); $this->fields_form[13]['form']['input']['filter_title_border_sizes']['name'] = $this->BuildInputs($this->getMP(2), 'filter_title_border_sizes'); $this->fields_form[13]['form']['input']['filter_border_sizes']['name'] = $this->BuildInputs($this->getMP(2), 'filter_border_sizes'); foreach (array('font_text'=>11, 'font_filter_title'=>13) as $font=>$wf) { if ($font_menu_string = Configuration::get($this->_prefix_st.strtoupper($font))) { $font_menu = explode(":", $font_menu_string); $font_menu = $font_menu[0]; $font_menu_key = str_replace(' ', '_', $font_menu); } else { $font_menu_key = $font_menu = $this->_font_inherit; } if(array_key_exists($font_menu_key, $this->googleFonts)) { $font_menu_array = array( $font_menu.':700' => '700', $font_menu.':italic' => 'italic', $font_menu.':700italic' => '700italic', ); foreach ($this->googleFonts[$font_menu_key]['variants'] as $g) { $font_menu_array[$font_menu.':'.$g] = $g; } foreach($font_menu_array AS $value){ $this->fields_form[$wf]['form']['input'][$font]['options']['query'][] = array( 'id'=> $font_menu.':'.($value=='regular' ? '400' : $value), 'name'=> $value, ); } } else { $this->fields_form[$wf]['form']['input'][$font]['options']['query'] = array( array('id'=> $font_menu,'name'=>'Normal'), array('id'=> $font_menu.':700','name'=>'Bold'), array('id'=> $font_menu.':italic','name'=>'Italic'), array('id'=> $font_menu.':700italic','name'=>'Bold & Italic'), ); } } $helper = new HelperForm(); $helper->show_toolbar = false; $helper->module = $this; $helper->table = $this->table; $lang = new Language((int)Configuration::get('PS_LANG_DEFAULT')); $helper->default_form_language = $lang->id; $helper->allow_employee_form_lang = Configuration::get('PS_BO_ALLOW_EMPLOYEE_FORM_LANG') ? Configuration::get('PS_BO_ALLOW_EMPLOYEE_FORM_LANG') : 0; $helper->identifier = $this->identifier; $helper->submit_action = 'save'.$this->name.'setting'; $helper->currentIndex = $this->context->link->getAdminLink('AdminModules', false).'&configure='.$this->name.'&tab_module='.$this->tab.'&module_name='.$this->name; $helper->token = Tools::getAdminTokenLite('AdminModules'); $helper->tpl_vars = array( 'fields_value' => $this->getConfigFieldsValues(), 'languages' => $this->context->controller->getLanguages(), 'id_language' => $this->context->language->id ); return $helper->generateForm($this->fields_form); } public function fontOptions() { $system = $google = array(); foreach($this->systemFonts as $v) $system[] = array('id'=>$v,'name'=>$v); foreach($this->googleFonts as $v) $google[] = array('id'=>$v['family'],'name'=>$v['family']); $module = new StFacetedSearch(); return array( array('name'=>$module->l('System Web fonts'),'query'=>$system), array('name'=>$module->l('Google Web Fonts'),'query'=>$google), ); } protected function initConfigFormFields() { $fields = $this->getFormFields(); $this->fields_form[2]['form'] = array( 'legend' => array( 'title' => $this->l('General settings'), 'icon' => 'icon-cogs' ), 'input' => $fields['setting'], 'submit' => array( 'title' => $this->l('Save all'), ), ); $this->fields_form[3]['form'] = array( 'legend' => array( 'title' => $this->l('Slider settings'), 'icon' => 'icon-cogs' ), 'input' => $fields['slider'], 'submit' => array( 'title' => $this->l('Save all'), ), ); $this->fields_form[5]['form'] = array( 'legend' => array( 'title' => $this->l('Slider color settings'), 'icon' => 'icon-cogs' ), 'input' => $fields['slider_color'], 'submit' => array( 'title' => $this->l('Save all'), ), ); $this->fields_form[22]['form'] = array( 'legend' => array( 'title' => $this->l('Basic color settings'), 'icon' => 'icon-cogs' ), 'input' => $fields['basic_color'], 'submit' => array( 'title' => $this->l('Save all'), ), ); $this->fields_form[11]['form'] = array( 'legend' => array( 'title' => $this->l('Filter group title'), 'icon' => 'icon-cogs' ), 'input' => $fields['block_title'], 'submit' => array( 'title' => $this->l('Save all'), ), ); $this->fields_form[4]['form'] = array( 'legend' => array( 'title' => $this->l('Filter group'), 'icon' => 'icon-cogs' ), 'input' => $fields['block'], 'submit' => array( 'title' => $this->l('Save all'), ), ); $this->fields_form[13]['form'] = array( 'legend' => array( 'title' => $this->l('Filter block'), 'icon' => 'icon-cogs' ), 'input' => $fields['filter'], 'submit' => array( 'title' => $this->l('Save all'), ), ); $this->fields_form[12]['form'] = array( 'legend' => array( 'title' => $this->l('Active filter items'), 'icon' => 'icon-cogs' ), 'input' => $fields['active_filter'], 'submit' => array( 'title' => $this->l('Save all'), ), ); $this->fields_form[14]['form'] = array( 'legend' => array( 'title' => $this->l('Loading effect'), 'icon' => 'icon-cogs' ), 'input' => $fields['loading'], 'submit' => array( 'title' => $this->l('Save all'), ), ); $this->fields_form[20]['form'] = array( 'legend' => array( 'title' => $this->l('Show more button for filter blocks'), 'icon' => 'icon-cogs' ), 'input' => $fields['showmore_blocks'], 'submit' => array( 'title' => $this->l('Save all'), ), ); $this->fields_form[21]['form'] = array( 'legend' => array( 'title' => $this->l('Show more button for filter items'), 'icon' => 'icon-cogs' ), 'input' => $fields['showmore_items'], 'submit' => array( 'title' => $this->l('Save all'), ), ); $this->fields_form[24]['form'] = array( 'legend' => array( 'title' => $this->l('The button to open slide-in sidebar'), 'icon' => 'icon-cogs' ), 'input' => $fields['triger_button'], 'submit' => array( 'title' => $this->l('Save all'), ), ); $this->fields_form[10]['form'] = array( 'legend' => array( 'title' => $this->l('Others'), 'icon' => 'icon-cogs' ), 'input' => $fields['other'], 'submit' => array( 'title' => $this->l('Save all'), ), ); /*$this->fields_form[6]['form'] = array( 'legend' => array( 'title' => $this->l('Left column'), 'icon' => 'icon-cogs' ), 'input' => $fields['left_column'], 'submit' => array( 'title' => $this->l('Save all'), ), );*/ $this->fields_form[7]['form'] = array( 'legend' => array( 'title' => $this->l('Center column'), 'icon' => 'icon-cogs' ), 'input' => $fields['center_column'], 'submit' => array( 'title' => $this->l('Save all'), ), ); $this->fields_form[8]['form'] = array( 'legend' => array( 'title' => $this->l('Center column as dropdown lists'), 'icon' => 'icon-cogs' ), 'input' => $fields['center_column_1'], 'submit' => array( 'title' => $this->l('Save all'), ), ); $this->fields_form[9]['form'] = array( 'legend' => array( 'title' => $this->l('Slide-in sidebar'), 'icon' => 'icon-cogs' ), 'input' => $fields['sidebar'], 'submit' => array( 'title' => $this->l('Save all'), ), ); $this->fields_form[15]['form'] = array( 'legend' => array( 'title' => $this->l('Button'), 'icon' => 'icon-cogs' ), 'input' => $fields['button'], 'submit' => array( 'title' => $this->l('Save all'), ), ); $this->fields_form[16]['form'] = array( 'legend' => array( 'title' => $this->l('Checkbox and radio'), 'icon' => 'icon-cogs' ), 'input' => $fields['checkbox'], 'submit' => array( 'title' => $this->l('Save all'), ), ); $this->fields_form[18]['form'] = array( 'legend' => array( 'title' => $this->l('Color box'), 'icon' => 'icon-cogs' ), 'input' => $fields['color'], 'submit' => array( 'title' => $this->l('Save all'), ), ); $this->fields_form[23]['form'] = array( 'legend' => array( 'title' => $this->l('Image'), 'icon' => 'icon-cogs' ), 'input' => $fields['img'], 'submit' => array( 'title' => $this->l('Save all'), ), ); $this->fields_form[17]['form'] = array( 'legend' => array( 'title' => $this->l('Select dropdown'), 'icon' => 'icon-cogs' ), 'input' => $fields['select'], 'submit' => array( 'title' => $this->l('Save all'), ), ); $moduleUrl = Tools::getProtocol(Tools::usingSecureMode()) . $_SERVER['HTTP_HOST'] . $this->getPathUri(); $this->fields_form[19]['form'] = array( 'legend' => array( 'title' => $this->l('Cron job'), 'icon' => 'icon-cogs' ), 'input' => array( array( 'type' => 'html', 'id' => '', 'label' => $this->l('Url for rebuilding price index:'), 'name' => $moduleUrl . 'stfacetedsearch-price-indexer.php' . '?token=' . substr(Tools::encrypt('stfacetedsearch/index'), 0, 10), ), array( 'type' => 'html', 'id' => '', 'label' => $this->l('Url for rebuilding attribute index and feature index:'), 'name' => $moduleUrl . 'stfacetedsearch-attribute-indexer.php' . '?token=' . substr(Tools::encrypt('stfacetedsearch/index'), 0, 10), ), ), ); } public function getFormFields() { require_once(dirname(__FILE__).'/formFields.php'); return getFormFields($this); } public function getFormFieldsDefault() { $default = array(); foreach ($this->getFormFields() as $key => $value) { if ($key == 'hook') { continue; } foreach ($value as $k => $v) { if (!$k || !is_array($v)) { continue; } if ($v['type'] == 'html' || $v['type'] == 'file') { continue; } $default[$k] = isset($v['default_value']) ? $v['default_value'] : ''; } } return $default; } private function getConfigFieldsValues() { $fields_values = array(); foreach ($this->getFormFieldsDefault() as $k => $v) { $fields_values[$k] = Configuration::get($this->_prefix_st.Tools::strtoupper($k)); } if (isset($fields_values['custom_css']) && $fields_values['custom_css']) $fields_values['custom_css'] = str_replace('¤', '\\', $fields_values['custom_css']); $arr = $this->getMP(1); foreach ($arr as $mp){ $fields_values['heading_paddings_'.$mp['id']] = Configuration::get($this->_prefix_st.strtoupper('heading_paddings_'.$mp['id'])); $fields_values['block_paddings_'.$mp['id']] = Configuration::get($this->_prefix_st.strtoupper('block_paddings_'.$mp['id'])); $fields_values['filter_paddings_'.$mp['id']] = Configuration::get($this->_prefix_st.strtoupper('filter_paddings_'.$mp['id'])); $fields_values['filter_title_paddings_'.$mp['id']] = Configuration::get($this->_prefix_st.strtoupper('filter_title_paddings_'.$mp['id'])); // $fields_values['button_paddings_'.$mp['id']] = Configuration::get($this->_prefix_st.strtoupper('button_paddings_'.$mp['id'])); $fields_values['active_paddings_'.$mp['id']] = Configuration::get($this->_prefix_st.strtoupper('active_paddings_'.$mp['id'])); } $arr = $this->getMP(2); foreach ($arr as $mp){ $fields_values['filter_title_border_sizes_'.$mp['id']] = Configuration::get($this->_prefix_st.strtoupper('filter_title_border_sizes_'.$mp['id'])); $fields_values['filter_border_sizes_'.$mp['id']] = Configuration::get($this->_prefix_st.strtoupper('filter_border_sizes_'.$mp['id'])); } $font_text_string = Configuration::get($this->_prefix_st.'FONT_TEXT'); $font_text_string && $font_text_string = explode(":", $font_text_string); $fields_values['font_text_list'] = $font_text_string ? $font_text_string[0] : ''; $font_filter_title_string = Configuration::get($this->_prefix_st.'FONT_FILTER_TITLE'); $font_filter_title_string && $font_filter_title_string = explode(":", $font_filter_title_string); $fields_values['font_filter_title_list'] = $font_filter_title_string ? $font_filter_title_string[0] : ''; return $fields_values; } public function displayLimitPostWarning($count) { $return = []; if ((ini_get('suhosin.post.max_vars') && ini_get('suhosin.post.max_vars') < $count) || (ini_get('suhosin.request.max_vars') && ini_get('suhosin.request.max_vars') < $count)) { $return['error_type'] = 'suhosin'; $return['post.max_vars'] = ini_get('suhosin.post.max_vars'); $return['request.max_vars'] = ini_get('suhosin.request.max_vars'); $return['needed_limit'] = $count + 100; } elseif (ini_get('max_input_vars') && ini_get('max_input_vars') < $count) { $return['error_type'] = 'conf'; $return['max_input_vars'] = ini_get('max_input_vars'); $return['needed_limit'] = $count + 100; } return $return; } private function query($sqlQuery) { return $this->getDatabase()->query($sqlQuery); } /** * Rebuild layered structure */ public function rebuildLayeredStructure() { @set_time_limit(0); /* Set memory limit to 128M only if current is lower */ $memoryLimit = Tools::getMemoryLimit(); if ($memoryLimit != -1 && $memoryLimit < 128 * 1024 * 1024) { @ini_set('memory_limit', '128M'); } $ret = true; /* Delete and re-create the layered categories table */ $this->getDatabase()->execute('DROP TABLE IF EXISTS ' . _DB_PREFIX_ . 'st_search_category'); $ret &= $this->getDatabase()->execute( 'CREATE TABLE IF NOT EXISTS `' . _DB_PREFIX_ . 'st_search_category` ( `id_st_search_category` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, `page` varchar(128) NOT NULL DEFAULT "category", `id_shop` INT(11) UNSIGNED NOT NULL, `id_object` INT(10) UNSIGNED NOT NULL, `id_value` INT(10) UNSIGNED NULL DEFAULT \'0\', `type` ENUM(\'category\',\'id_feature\',\'id_attribute_group\',\'quantity\',\'condition\',\'manufacturer\',\'weight\',\'price\') NOT NULL, `position` INT(10) UNSIGNED NOT NULL, `filter_type` int(10) UNSIGNED NOT NULL DEFAULT 0, `filter_show_limit` int(10) UNSIGNED NOT NULL DEFAULT 0, `id_st_search_filter` int(10) UNSIGNED NOT NULL DEFAULT 0, KEY `id_object_shop` (`id_object`, `id_shop`, `type`, `page`, `id_value`, `position`), KEY `id_object` (`id_object`,`type`,`page`) ) ENGINE=' . _MYSQL_ENGINE_ . ' DEFAULT CHARSET=utf8;' ); $ret &= $this->getDatabase()->execute( 'CREATE TABLE IF NOT EXISTS `' . _DB_PREFIX_ . 'st_search_filter` ( `id_st_search_filter` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, `page` varchar(128) NOT NULL DEFAULT "category", `name` VARCHAR(64) DEFAULT NULL, `filters` LONGTEXT NULL, `n_categories` INT(10) UNSIGNED NOT NULL, `active` tinyint(1) unsigned NOT NULL DEFAULT 1, `date_add` DATETIME NOT NULL ) ENGINE=' . _MYSQL_ENGINE_ . ' DEFAULT CHARSET=utf8;' ); $ret &= $this->getDatabase()->execute( 'CREATE TABLE IF NOT EXISTS `' . _DB_PREFIX_ . 'st_search_filter_block` ( `hash` CHAR(32) NOT NULL DEFAULT "" PRIMARY KEY, `data` MEDIUMTEXT NULL ) ENGINE=' . _MYSQL_ENGINE_ . ' DEFAULT CHARSET=utf8;' ); $ret &= $this->getDatabase()->execute( 'CREATE TABLE IF NOT EXISTS `' . _DB_PREFIX_ . 'st_search_filter_shop` ( `id_st_search_filter` INT(10) UNSIGNED NOT NULL, `id_shop` INT(11) UNSIGNED NOT NULL, PRIMARY KEY (`id_st_search_filter`, `id_shop`), KEY `id_shop` (`id_shop`) ) ENGINE=' . _MYSQL_ENGINE_ . ' DEFAULT CHARSET=utf8;' ); return $ret; } /** * Build layered cache * * @param array $productsIds * @param array $categoriesIds * @param bool $rebuildLayeredCategories */ public function rebuildLayeredCache($productsIds = [], $categoriesIds = [], $rebuildLayeredCategories = true) { @set_time_limit(0); $filterData = ['categories' => []]; /* Set memory limit to 128M only if current is lower */ $memoryLimit = Tools::getMemoryLimit(); if ($memoryLimit != -1 && $memoryLimit < 128 * 1024 * 1024) { @ini_set('memory_limit', '128M'); } $db = $this->getDatabase(); $nCategories = []; $doneCategories = []; $alias = 'product_shop'; $joinProduct = Shop::addSqlAssociation('product', 'p'); $joinProductAttribute = Shop::addSqlAssociation('product_attribute', 'pa'); $attributeGroups = $this->query( 'SELECT a.id_attribute, a.id_attribute_group FROM ' . _DB_PREFIX_ . 'attribute a LEFT JOIN ' . _DB_PREFIX_ . 'product_attribute_combination pac ON (pac.id_attribute = a.id_attribute) LEFT JOIN ' . _DB_PREFIX_ . 'product_attribute pa ON (pa.id_product_attribute = pac.id_product_attribute) LEFT JOIN ' . _DB_PREFIX_ . 'product p ON (p.id_product = pa.id_product) ' . $joinProduct . $joinProductAttribute . ' LEFT JOIN ' . _DB_PREFIX_ . 'category_product cp ON (cp.id_product = p.id_product) LEFT JOIN ' . _DB_PREFIX_ . 'category c ON (c.id_category = cp.id_category) WHERE c.active = 1' . (count($categoriesIds) ? ' AND cp.id_category IN (' . implode(',', array_map('intval', $categoriesIds)) . ')' : '') . ' AND ' . $alias . '.active = 1 AND ' . $alias . '.`visibility` IN ("both", "catalog") ' . (count($productsIds) ? 'AND p.id_product IN (' . implode(',', array_map('intval', $productsIds)) . ')' : '') ); $attributeGroupsById = []; while ($row = $db->nextRow($attributeGroups)) { $attributeGroupsById[(int) $row['id_attribute']] = (int) $row['id_attribute_group']; } $features = $this->query( 'SELECT fv.id_feature_value, fv.id_feature FROM ' . _DB_PREFIX_ . 'feature_value fv LEFT JOIN ' . _DB_PREFIX_ . 'feature_product fp ON (fp.id_feature_value = fv.id_feature_value) LEFT JOIN ' . _DB_PREFIX_ . 'product p ON (p.id_product = fp.id_product) ' . $joinProduct . ' LEFT JOIN ' . _DB_PREFIX_ . 'category_product cp ON (cp.id_product = p.id_product) LEFT JOIN ' . _DB_PREFIX_ . 'category c ON (c.id_category = cp.id_category) WHERE c.active = 1' . (count($categoriesIds) ? ' AND cp.id_category IN (' . implode(',', array_map('intval', $categoriesIds)) . ')' : '') . ' AND ' . $alias . '.active = 1 AND ' . $alias . '.`visibility` IN ("both", "catalog") ' . (count($productsIds) ? 'AND p.id_product IN (' . implode(',', array_map('intval', $productsIds)) . ')' : '') ); $featuresById = []; while ($row = $db->nextRow($features)) { $featuresById[(int) $row['id_feature_value']] = (int) $row['id_feature']; } $result = $this->query( 'SELECT p.id_product, GROUP_CONCAT(DISTINCT fv.id_feature_value) features, GROUP_CONCAT(DISTINCT cp.id_category) categories, GROUP_CONCAT(DISTINCT pac.id_attribute) attributes FROM ' . _DB_PREFIX_ . 'product p LEFT JOIN ' . _DB_PREFIX_ . 'category_product cp ON (cp.id_product = p.id_product) LEFT JOIN ' . _DB_PREFIX_ . 'category c ON (c.id_category = cp.id_category) LEFT JOIN ' . _DB_PREFIX_ . 'feature_product fp ON (fp.id_product = p.id_product) LEFT JOIN ' . _DB_PREFIX_ . 'feature_value fv ON (fv.id_feature_value = fp.id_feature_value) LEFT JOIN ' . _DB_PREFIX_ . 'product_attribute pa ON (pa.id_product = p.id_product) ' . $joinProduct . $joinProductAttribute . ' LEFT JOIN ' . _DB_PREFIX_ . 'product_attribute_combination pac ON (pac.id_product_attribute = pa.id_product_attribute) WHERE c.active = 1' . (count($categoriesIds) ? ' AND cp.id_category IN (' . implode(',', array_map('intval', $categoriesIds)) . ')' : '') . ' AND ' . $alias . '.active = 1 AND ' . $alias . '.`visibility` IN ("both", "catalog") ' . (count($productsIds) ? 'AND p.id_product IN (' . implode(',', array_map('intval', $productsIds)) . ')' : '') . ' GROUP BY p.id_product' ); $shopList = Shop::getShops(false, null, true); $toInsert = false; while ($product = $db->nextRow($result)) { $a = $c = $f = []; if (!empty($product['attributes'])) { $a = array_flip(explode(',', $product['attributes'])); } if (!empty($product['categories'])) { $c = array_flip(explode(',', $product['categories'])); } if (!empty($product['features'])) { $f = array_flip(explode(',', $product['features'])); } $filterData['shop_list'] = $shopList; foreach ($c as $idCategory => $category) { if (!in_array($idCategory, $filterData['categories'])) { $filterData['categories'][] = $idCategory; } if (!isset($nCategories[(int) $idCategory])) { $nCategories[(int) $idCategory] = 1; } if (!isset($doneCategories[(int) $idCategory]['cat'])) { $filterData['layered_selection_subcategories'] = ['filter_type' => Converter::WIDGET_TYPE_CHECKBOX, 'filter_show_limit' => 0]; $doneCategories[(int) $idCategory]['cat'] = true; $toInsert = true; } if (is_array($attributeGroupsById) && count($attributeGroupsById) > 0) { foreach ($a as $kAttribute => $attribute) { if (!isset($doneCategories[(int) $idCategory]['a' . (int) $attributeGroupsById[(int) $kAttribute]])) { $filterData['layered_selection_ag_' . (int) $attributeGroupsById[(int) $kAttribute]] = ['filter_type' => Converter::WIDGET_TYPE_CHECKBOX, 'filter_show_limit' => 0]; $doneCategories[(int) $idCategory]['a' . (int) $attributeGroupsById[(int) $kAttribute]] = true; $toInsert = true; } } } if (is_array($attributeGroupsById) && count($attributeGroupsById) > 0) { foreach ($f as $kFeature => $feature) { if (!isset($doneCategories[(int) $idCategory]['f' . (int) $featuresById[(int) $kFeature]])) { $filterData['layered_selection_feat_' . (int) $featuresById[(int) $kFeature]] = ['filter_type' => Converter::WIDGET_TYPE_CHECKBOX, 'filter_show_limit' => 0]; $doneCategories[(int) $idCategory]['f' . (int) $featuresById[(int) $kFeature]] = true; $toInsert = true; } } } if (!isset($doneCategories[(int) $idCategory]['q'])) { $filterData['layered_selection_stock'] = ['filter_type' => Converter::WIDGET_TYPE_CHECKBOX, 'filter_show_limit' => 0]; $doneCategories[(int) $idCategory]['q'] = true; $toInsert = true; } if (!isset($doneCategories[(int) $idCategory]['m'])) { $filterData['layered_selection_manufacturer'] = ['filter_type' => Converter::WIDGET_TYPE_CHECKBOX, 'filter_show_limit' => 0]; $doneCategories[(int) $idCategory]['m'] = true; $toInsert = true; } if (!isset($doneCategories[(int) $idCategory]['c'])) { $filterData['layered_selection_condition'] = ['filter_type' => Converter::WIDGET_TYPE_CHECKBOX, 'filter_show_limit' => 0]; $doneCategories[(int) $idCategory]['c'] = true; $toInsert = true; } if (!isset($doneCategories[(int) $idCategory]['w'])) { $filterData['layered_selection_weight_slider'] = ['filter_type' => Converter::WIDGET_TYPE_CHECKBOX, 'filter_show_limit' => 0]; $doneCategories[(int) $idCategory]['w'] = true; $toInsert = true; } if (!isset($doneCategories[(int) $idCategory]['p'])) { $filterData['layered_selection_price_slider'] = ['filter_type' => Converter::WIDGET_TYPE_CHECKBOX, 'filter_show_limit' => 0]; $doneCategories[(int) $idCategory]['p'] = true; $toInsert = true; } } } if ($toInsert) { $this->getDatabase()->execute('INSERT INTO ' . _DB_PREFIX_ . 'st_search_filter(name, filters, n_categories, date_add) VALUES (\'' . sprintf($this->l('My template %s'), date('Y-m-d')) . '\', \'' . pSQL(serialize($filterData)) . '\', ' . count($filterData['categories']) . ', NOW())'); $last_id = $this->getDatabase()->Insert_ID(); $this->getDatabase()->execute('DELETE FROM ' . _DB_PREFIX_ . 'st_search_filter_shop WHERE `id_st_search_filter` = ' . $last_id); foreach ($shopList as $idShop) { $this->getDatabase()->execute('INSERT INTO ' . _DB_PREFIX_ . 'st_search_filter_shop (`id_st_search_filter`, `id_shop`) VALUES(' . $last_id . ', ' . (int) $idShop . ')'); } if ($rebuildLayeredCategories) { $this->buildLayeredCategories(); } } } /** * Build layered categories */ public function buildLayeredCategories() { // Get all filter template $res = $this->getDatabase()->executeS('SELECT * FROM ' . _DB_PREFIX_ . 'st_search_filter WHERE `active` = 1 ORDER BY date_add DESC'); $objects = []; // Clear cache $this->invalidateLayeredFilterBlockCache(); // Remove all from st_search_category $this->getDatabase()->execute('TRUNCATE ' . _DB_PREFIX_ . 'st_search_category'); if (!count($res)) { // No filters templates defined, nothing else to do return true; } $sqlInsertPrefix = 'INSERT INTO ' . _DB_PREFIX_ . 'st_search_category (page, id_object, id_shop, id_value, type, position, filter_show_limit, filter_type, id_st_search_filter) VALUES '; $sqlInsert = ''; $nbSqlValuesToInsert = 0; foreach ($res as $filterTemplate) { $data = Tools::unSerialize($filterTemplate['filters']); foreach ($data['shop_list'] as $idShop) { if (!isset($objects[$idShop][$filterTemplate['page']])) { $objects[$idShop][$filterTemplate['page']] = []; } $dataObject = []; if ($filterTemplate['page'] == 'category') { $dataObject = $data['categories']; } elseif ($filterTemplate['page'] == 'manufacturer') { $dataObject = $data['manufacturers']; } else { $dataObject = [0]; } foreach ($dataObject as $idObject) { $n = 0; if (in_array($idObject, $objects[$idShop][$filterTemplate['page']])) { continue; } // Last definition, erase previous objects defined $objects[$idShop][$filterTemplate['page']][] = $idObject; foreach ($data as $key => $value) { if (substr($key, 0, 17) == 'layered_selection') { $type = $value['filter_type']; $limit = $value['filter_show_limit']; ++$n; if ($key == 'layered_selection_stock') { $sqlInsert .= '("'.$filterTemplate['page'].'", ' . (int) $idObject . ', ' . (int) $idShop . ', NULL,\'quantity\',' . (int) $n . ', ' . (int) $limit . ', ' . (int) $type . ', '.$filterTemplate['id_st_search_filter'].'),'; } elseif ($key == 'layered_selection_subcategories') { $sqlInsert .= '("'.$filterTemplate['page'].'", ' . (int) $idObject . ', ' . (int) $idShop . ', NULL,\'category\',' . (int) $n . ', ' . (int) $limit . ', ' . (int) $type . ', '.$filterTemplate['id_st_search_filter'].'),'; } elseif ($key == 'layered_selection_condition') { $sqlInsert .= '("'.$filterTemplate['page'].'", ' . (int) $idObject . ', ' . (int) $idShop . ', NULL,\'condition\',' . (int) $n . ', ' . (int) $limit . ', ' . (int) $type . ', '.$filterTemplate['id_st_search_filter'].'),'; } elseif ($key == 'layered_selection_weight_slider') { $sqlInsert .= '("'.$filterTemplate['page'].'", ' . (int) $idObject . ', ' . (int) $idShop . ', NULL,\'weight\',' . (int) $n . ', ' . (int) $limit . ', ' . (int) $type . ', '.$filterTemplate['id_st_search_filter'].'),'; } elseif ($key == 'layered_selection_price_slider') { $sqlInsert .= '("'.$filterTemplate['page'].'", ' . (int) $idObject . ', ' . (int) $idShop . ', NULL,\'price\',' . (int) $n . ', ' . (int) $limit . ', ' . (int) $type . ', '.$filterTemplate['id_st_search_filter'].'),'; } elseif ($key == 'layered_selection_manufacturer') { $sqlInsert .= '("'.$filterTemplate['page'].'", ' . (int) $idObject . ', ' . (int) $idShop . ', NULL,\'manufacturer\',' . (int) $n . ', ' . (int) $limit . ', ' . (int) $type . ', '.$filterTemplate['id_st_search_filter'].'),'; } elseif (substr($key, 0, 21) == 'layered_selection_ag_') { $sqlInsert .= '("'.$filterTemplate['page'].'", ' . (int) $idObject . ', ' . (int) $idShop . ', ' . (int) str_replace('layered_selection_ag_', '', $key) . ', \'id_attribute_group\',' . (int) $n . ', ' . (int) $limit . ', ' . (int) $type . ', '.$filterTemplate['id_st_search_filter'].'),'; } elseif (substr($key, 0, 23) == 'layered_selection_feat_') { $sqlInsert .= '("'.$filterTemplate['page'].'", ' . (int) $idObject . ', ' . (int) $idShop . ', ' . (int) str_replace('layered_selection_feat_', '', $key) . ', \'id_feature\',' . (int) $n . ', ' . (int) $limit . ', ' . (int) $type . ', '.$filterTemplate['id_st_search_filter'].'),'; } ++$nbSqlValuesToInsert; if ($nbSqlValuesToInsert >= 100) { $this->getDatabase()->execute($sqlInsertPrefix . rtrim($sqlInsert, ',')); $sqlInsert = ''; $nbSqlValuesToInsert = 0; } } } } } } if ($nbSqlValuesToInsert) { $this->getDatabase()->execute($sqlInsertPrefix . rtrim($sqlInsert, ',')); } } /** * Render template * * @param string $template * @param array $params * * @return string */ public function render($template, array $params = []) { $this->context->smarty->assign($params); return $this->display(__FILE__, $template); } /** * Check if link rewrite are availables and corrects * * @param array $params */ public function checkLinksRewrite($params) { foreach (Language::getLanguages(false) as $language) { $idLang = $language['id_lang']; $urlNameLang = Tools::getValue('url_name_' . $idLang); if ($urlNameLang && Tools::link_rewrite($urlNameLang) != strtolower($urlNameLang)) { $params['errors'][] = Tools::displayError( $this->l( '"%s" is not a valid url', [$urlNameLang], 'Modules.Facetedsearch.Admin' ) ); } } } /** * Dispatch hooks * * @param string $methodName * @param array $arguments */ public function __call($methodName, array $arguments) { return $this->getHookDispatcher()->dispatch( $methodName, !empty($arguments[0]) ? $arguments[0] : [] ); } /** * Invalid filter block cache */ public function invalidateLayeredFilterBlockCache() { return $this->getDatabase()->execute('TRUNCATE TABLE ' . _DB_PREFIX_ . 'st_search_filter_block'); } /** * Install price indexes table */ public function rebuildPriceIndexTable() { $this->getDatabase()->execute('DROP TABLE IF EXISTS `' . _DB_PREFIX_ . 'st_search_price_index`'); $this->getDatabase()->execute( 'CREATE TABLE `' . _DB_PREFIX_ . 'st_search_price_index` ( `id_product` INT NOT NULL, `id_currency` INT NOT NULL, `id_shop` INT NOT NULL, '.(Module::isEnabled('stproductsbyattrs') ? '`id_product_attribute` INT NOT NULL,' : '').' `price_min` DECIMAL(20, 5) NOT NULL, `price_max` DECIMAL(20, 5) NOT NULL, `id_country` INT NOT NULL, PRIMARY KEY (`id_product`,'.(Module::isEnabled('stproductsbyattrs') ? '`id_product_attribute`,' : '').' `id_currency`, `id_shop`, `id_country`), INDEX `id_currency` (`id_currency`), INDEX `price_min` (`price_min`), INDEX `price_max` (`price_max`) ) ENGINE=' . _MYSQL_ENGINE_ . ' DEFAULT CHARSET=utf8;' ); } /** * create table product attribute. */ private function installProductAttributeTable() { $this->getDatabase()->execute('DROP TABLE IF EXISTS `' . _DB_PREFIX_ . 'st_search_product_attribute`'); $this->getDatabase()->execute( 'CREATE TABLE `' . _DB_PREFIX_ . 'st_search_product_attribute` ( `id_attribute` int(10) unsigned NOT NULL, `id_product` int(10) unsigned NOT NULL, `id_attribute_group` int(10) unsigned NOT NULL DEFAULT "0", `id_shop` int(10) unsigned NOT NULL DEFAULT "1", PRIMARY KEY (`id_attribute`, `id_product`, `id_shop`), UNIQUE KEY `id_attribute_group` (`id_attribute_group`,`id_attribute`,`id_product`, `id_shop`) ) ENGINE=' . _MYSQL_ENGINE_ . ' DEFAULT CHARSET=utf8;' ); } private function installFacetItemTable() { $this->getDatabase()->execute('DROP TABLE IF EXISTS `' . _DB_PREFIX_ . 'st_search_facet_item`'); $this->getDatabase()->execute( 'CREATE TABLE `' . _DB_PREFIX_ . 'st_search_facet_item` ( `id_st_search_facet_item` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT, `id_st_search_filter` int(10) unsigned NOT NULL, `facet_type` varchar(64) NOT NULL, `facet_item_k` int(10) unsigned NOT NULL, `id_shop` int(10) unsigned NOT NULL DEFAULT 1, `kaiguan` tinyint(1) unsigned NOT NULL DEFAULT 0, `position` int(10) unsigned NOT NULL DEFAULT 0, `collapsed` tinyint(1) unsigned NOT NULL DEFAULT 0, `collapsed_mobile` tinyint(1) unsigned NOT NULL DEFAULT 0, `pips` tinyint(1) unsigned NOT NULL DEFAULT 0, `snap` tinyint(1) unsigned NOT NULL DEFAULT 0, `tooltips` tinyint(1) unsigned NOT NULL DEFAULT 0, `bar_bg_left` varchar(7) DEFAULT NULL, `bar_bg_right` varchar(7) DEFAULT NULL, `bg` varchar(7) DEFAULT NULL, `per_row` tinyint(1) unsigned NOT NULL DEFAULT 0, `per_row_mobile` tinyint(1) unsigned NOT NULL DEFAULT 0, `multi` tinyint(1) unsigned NOT NULL DEFAULT 1, `zhuangtai` tinyint(1) unsigned NOT NULL DEFAULT 1, `min_width` int(10) unsigned NOT NULL DEFAULT 0, `img_width` int(10) unsigned NOT NULL DEFAULT 0, `show_img` tinyint(1) unsigned NOT NULL DEFAULT 0, `text_align` tinyint(1) unsigned NOT NULL DEFAULT 0, `tb_mar` varchar(7) DEFAULT NULL, `lr_mar` varchar(7) DEFAULT NULL, `tb_pad` varchar(7) DEFAULT NULL, `lr_pad` varchar(7) DEFAULT NULL, `border` varchar(7) DEFAULT NULL, `pad` varchar(7) DEFAULT NULL, `vertical` tinyint(1) unsigned NOT NULL DEFAULT 0, `vertical_height` varchar(7) DEFAULT NULL, `auto_sort` tinyint(1) unsigned NOT NULL DEFAULT 1, PRIMARY KEY (`id_st_search_facet_item`) ) ENGINE=' . _MYSQL_ENGINE_ . ' DEFAULT CHARSET=utf8;' ); /*`numerical` tinyint(1) unsigned NOT NULL DEFAULT 0, `numerical_step` int(10) unsigned NOT NULL DEFAULT 1,*/ $this->getDatabase()->execute('DROP TABLE IF EXISTS `' . _DB_PREFIX_ . 'st_search_facet_af`'); $this->getDatabase()->execute( 'CREATE TABLE `' . _DB_PREFIX_ . 'st_search_facet_af` ( `id_st_search_facet_item` int(10) unsigned NOT NULL, `facet_item_value_k` int(10) unsigned NOT NULL, `position` int(10) unsigned NOT NULL DEFAULT 0, `zhuangtai` tinyint(1) unsigned NOT NULL DEFAULT 0, `img` varchar(255) DEFAULT NULL, `width` int(10) unsigned NOT NULL DEFAULT 0, `height` int(10) unsigned NOT NULL DEFAULT 0 ) ENGINE=' . _MYSQL_ENGINE_ . ' DEFAULT CHARSET=utf8;' ); } /** * Install indexable attribute table */ private function installIndexableAttributeTable() { // Attributes Groups $this->getDatabase()->execute('DROP TABLE IF EXISTS `' . _DB_PREFIX_ . 'st_search_indexable_attribute_group`'); $this->getDatabase()->execute( 'CREATE TABLE `' . _DB_PREFIX_ . 'st_search_indexable_attribute_group` ( `id_attribute_group` INT NOT NULL, `indexable` BOOL NOT NULL DEFAULT 0, PRIMARY KEY (`id_attribute_group`) ) ENGINE=' . _MYSQL_ENGINE_ . ' DEFAULT CHARSET=utf8;' ); $this->getDatabase()->execute( 'INSERT INTO `' . _DB_PREFIX_ . 'st_search_indexable_attribute_group` SELECT id_attribute_group, 1 FROM `' . _DB_PREFIX_ . 'attribute_group`' ); $this->getDatabase()->execute('DROP TABLE IF EXISTS `' . _DB_PREFIX_ . 'st_search_indexable_attribute_group_lang_value`'); $this->getDatabase()->execute( 'CREATE TABLE `' . _DB_PREFIX_ . 'st_search_indexable_attribute_group_lang_value` ( `id_attribute_group` INT NOT NULL, `id_lang` INT NOT NULL, `url_name` VARCHAR(128), `meta_title` VARCHAR(128), PRIMARY KEY (`id_attribute_group`, `id_lang`) ) ENGINE=' . _MYSQL_ENGINE_ . ' DEFAULT CHARSET=utf8;' ); // Attributes $this->getDatabase()->execute('DROP TABLE IF EXISTS `' . _DB_PREFIX_ . 'st_search_indexable_attribute_lang_value`'); $this->getDatabase()->execute( 'CREATE TABLE `' . _DB_PREFIX_ . 'st_search_indexable_attribute_lang_value` ( `id_attribute` INT NOT NULL, `id_lang` INT NOT NULL, `url_name` VARCHAR(128), `meta_title` VARCHAR(128), PRIMARY KEY (`id_attribute`, `id_lang`) ) ENGINE=' . _MYSQL_ENGINE_ . ' DEFAULT CHARSET=utf8;' ); // Features $this->getDatabase()->execute('DROP TABLE IF EXISTS `' . _DB_PREFIX_ . 'st_search_indexable_feature`'); $this->getDatabase()->execute( 'CREATE TABLE `' . _DB_PREFIX_ . 'st_search_indexable_feature` ( `id_feature` INT NOT NULL, `indexable` BOOL NOT NULL DEFAULT 0, PRIMARY KEY (`id_feature`) ) ENGINE=' . _MYSQL_ENGINE_ . ' DEFAULT CHARSET=utf8;' ); $this->getDatabase()->execute( 'INSERT INTO `' . _DB_PREFIX_ . 'st_search_indexable_feature` SELECT id_feature, 1 FROM `' . _DB_PREFIX_ . 'feature`' ); $this->getDatabase()->execute('DROP TABLE IF EXISTS `' . _DB_PREFIX_ . 'st_search_indexable_feature_lang_value`'); $this->getDatabase()->execute( 'CREATE TABLE `' . _DB_PREFIX_ . 'st_search_indexable_feature_lang_value` ( `id_feature` INT NOT NULL, `id_lang` INT NOT NULL, `url_name` VARCHAR(128) NOT NULL, `meta_title` VARCHAR(128), PRIMARY KEY (`id_feature`, `id_lang`) ) ENGINE=' . _MYSQL_ENGINE_ . ' DEFAULT CHARSET=utf8;' ); // Features values $this->getDatabase()->execute('DROP TABLE IF EXISTS `' . _DB_PREFIX_ . 'st_search_indexable_feature_value_lang_value`'); $this->getDatabase()->execute( 'CREATE TABLE `' . _DB_PREFIX_ . 'st_search_indexable_feature_value_lang_value` ( `id_feature_value` INT NOT NULL, `id_lang` INT NOT NULL, `url_name` VARCHAR(128), `meta_title` VARCHAR(128), PRIMARY KEY (`id_feature_value`, `id_lang`) ) ENGINE=' . _MYSQL_ENGINE_ . ' DEFAULT CHARSET=utf8;' ); } /** * Index prices * * @param $cursor int last indexed id_product * @param bool $full * @param bool $ajax * @param bool $smart * * @return int */ private function indexPrices($cursor = 0, $full = false, $ajax = false, $smart = false) { if ($full) { $nbProducts = (int) $this->getDatabase()->getValue( 'SELECT count(DISTINCT p.`id_product`) ' . 'FROM ' . _DB_PREFIX_ . 'product p ' . 'INNER JOIN `' . _DB_PREFIX_ . 'product_shop` ps ' . 'ON (ps.`id_product` = p.`id_product` AND ps.`active` = 1 AND ps.`visibility` IN ("both", "catalog"))' ); } else { $nbProducts = (int) $this->getDatabase()->getValue( 'SELECT COUNT(DISTINCT p.`id_product`) ' . 'FROM `' . _DB_PREFIX_ . 'product` p ' . 'INNER JOIN `' . _DB_PREFIX_ . 'product_shop` ps ON (ps.`id_product` = p.`id_product` AND ps.`active` = 1 AND ps.`visibility` IN ("both", "catalog")) ' . 'LEFT JOIN `' . _DB_PREFIX_ . 'st_search_price_index` psi ON (psi.id_product = p.id_product) ' . 'WHERE psi.id_product IS NULL' ); } $maxExecutiontime = @ini_get('max_execution_time'); if ($maxExecutiontime > 5 || $maxExecutiontime <= 0) { $maxExecutiontime = 5; } $startTime = microtime(true); $indexedProducts = 0; $length = 20; do { $lastCursor = $cursor; $cursor = (int) $this->indexPricesUnbreakable((int) $cursor, $full, $smart, $length); if ($cursor == 0) { $lastCursor = $cursor; break; } $time_elapsed = microtime(true) - $startTime; $indexedProducts += $length; } while ( $cursor < $nbProducts && (Tools::getMemoryLimit() == -1 || Tools::getMemoryLimit() > memory_get_peak_usage()) && $time_elapsed < $maxExecutiontime ); if (($nbProducts > 0 && !$full || $cursor != $lastCursor && $full) && !$ajax) { $token = substr(Tools::encrypt('stfacetedsearch/index'), 0, 10); $domain = Tools::usingSecureMode() ? Tools::getShopDomainSsl(true) : Tools::getShopDomain(true); $this->indexPrices((int) $cursor, (int) $full); return $cursor; } if ($ajax && $nbProducts > 0 && $cursor != $lastCursor && $full) { return json_encode([ 'cursor' => $cursor, 'count' => $indexedProducts, ]); } if ($ajax && $nbProducts > 0 && !$full) { return json_encode([ 'cursor' => $cursor, 'count' => $nbProducts, ]); } Configuration::updateGlobalValue('PS_LAYERED_INDEXED', 1); if ($ajax) { return json_encode([ 'result' => 'ok', ]); } return -1; } /** * Index prices unbreakable * * @param $cursor int last indexed id_product * @param bool $full All products, otherwise only indexed products * @param bool $smart Delete before reindex * @param int $length nb of products to index * * @return int */ private function indexPricesUnbreakable($cursor, $full = false, $smart = false, $length = 100) { if (null === $cursor) { $cursor = 0; } if ($full) { $query = 'SELECT p.`id_product` ' . 'FROM `' . _DB_PREFIX_ . 'product` p ' . 'INNER JOIN `' . _DB_PREFIX_ . 'product_shop` ps ' . 'ON (ps.`id_product` = p.`id_product` AND ps.`active` = 1 AND ps.`visibility` IN ("both", "catalog")) ' . 'WHERE p.id_product > ' . (int) $cursor . ' ' . 'GROUP BY p.`id_product` ' . 'ORDER BY p.`id_product` LIMIT 0,' . (int) $length; } else { $query = 'SELECT p.`id_product` ' . 'FROM `' . _DB_PREFIX_ . 'product` p ' . 'INNER JOIN `' . _DB_PREFIX_ . 'product_shop` ps ' . 'ON (ps.`id_product` = p.`id_product` AND ps.`active` = 1 AND ps.`visibility` IN ("both", "catalog")) ' . 'LEFT JOIN `' . _DB_PREFIX_ . 'st_search_price_index` psi ON (psi.id_product = p.id_product) ' . 'WHERE psi.id_product IS NULL ' . 'GROUP BY p.`id_product` ' . 'ORDER BY p.`id_product` LIMIT 0,' . (int) $length; } $lastIdProduct = 0; foreach ($this->getDatabase()->executeS($query) as $product) { $this->indexProductPrices((int) $product['id_product'], ($smart && $full)); $lastIdProduct = $product['id_product']; } return (int) $lastIdProduct; } public function hookDisplayHeader(array $params) { // $this->context->controller->addJS($this->_path.'views/js/nouislider.min.js'); $this->context->controller->addJS($this->_path.'views/js/nouislider.js'); $this->context->controller->addJS($this->_path.'views/js/front.js'); $this->context->controller->addCSS($this->_path.'views/dist/front.css'); $this->context->controller->addCSS($this->_path.'views/css/nouislider.min.css'); $this->context->controller->addCSS($this->_path.'views/font/fontello-codes.css'); if (!$this->isCached('module:stfacetedsearch/views/templates/hook/header.tpl', $this->getCacheId())) { $prefix = '.st-range-box'; $custom_css = ''; $show_on = Configuration::get($this->_prefix_st.'SHOW_ON'); if($handle_bg = Configuration::get($this->_prefix_st.'HANDLE_BG')) $custom_css .= $prefix.' .noUi-handle{background-color:'.$handle_bg.';}'; if($bar_bg = Configuration::get($this->_prefix_st.'BAR_BG')){ $custom_css .= $prefix.' .noUi-target{background-color:'.$bar_bg.';}'; } if($border_color = Configuration::get($this->_prefix_st.'BORDER_COLOR')) $custom_css .= $prefix.' .noUi-target{border-color:'.$border_color.';}'; if($handle_border_color = Configuration::get($this->_prefix_st.'HANDLE_BORDER_COLOR')) $custom_css .= $prefix.' .noUi-handle{border-color:'.$handle_border_color.';}'; if($connect_bg = Configuration::get($this->_prefix_st.'CONNECT_BG')){ $custom_css .= $prefix.' .noUi-connect{background-color:'.$connect_bg.';}'; if($bar_bg_right = Configuration::get($this->_prefix_st.'BAR_BG_RIGHT')){ $custom_css .= $prefix.' .noUi-connect{background: -webkit-gradient(linear,left top,right top,color-stop(0%,'.$connect_bg.'),color-stop(100%,'.$bar_bg_right.')); background: -webkit-linear-gradient(left,'.$connect_bg.' 0%,'.$bar_bg_right.' 100%);}'; } } if($topbar_text_color = Configuration::get($this->_prefix_st.'TOPBAR_TEXT_COLOR')) $custom_css .= $prefix.' .st-range-bar{color:'.$topbar_text_color.';}'; if($pips_color = Configuration::get($this->_prefix_st.'PIPS_COLOR')) $custom_css .= $prefix.' .noUi-pips{color:'.$pips_color.';}'; if($tooltips_bg = Configuration::get($this->_prefix_st.'TOOLTIPS_BG')) $custom_css .= $prefix.' .noUi-tooltip{background-color:'.$tooltips_bg.';}'; if($tooltips_color = Configuration::get($this->_prefix_st.'TOOLTIPS_COLOR')) $custom_css .= $prefix.' .noUi-tooltip{color:'.$tooltips_color.';}'; if($tooltips_border = Configuration::get($this->_prefix_st.'TOOLTIPS_BORDER')) $custom_css .= $prefix.' .noUi-tooltip{border-color:'.$tooltips_border.';}'; $bar_height = Configuration::get($this->_prefix_st.'BAR_HEIGHT'); $handle_height = Configuration::get($this->_prefix_st.'HANDLE_HEIGHT'); // $vertical = Configuration::get($this->_prefix_st.'VERTICAL'); $range_style = (int)Configuration::get($this->_prefix_st.'RANGE_STYLE'); if($bar_height){ $custom_css .= $prefix.' .noUi-horizontal{height:'.$bar_height.'px;}'; $custom_css .= $prefix.' .noUi-vertical{width:'.$bar_height.'px;}'; } if($bar_height || $handle_height){ // if($bar_height) $tmp_bar_height = $bar_height; else $tmp_bar_height = $range_style ? 10 : 18; if($handle_height) $tmp_handle_height = $handle_height; else $tmp_handle_height = $range_style ? 16 : 28; if($tmp_handle_height>=$tmp_bar_height+2){ $custom_css .= $prefix.' .noUi-horizontal .noUi-handle{top:-'.Tools::ps_round(($tmp_handle_height-$tmp_bar_height+2)/2).'px;}'; $custom_css .= $prefix.' .noUi-vertical .noUi-handle{left:-'.Tools::ps_round(($tmp_handle_height-$tmp_bar_height+2)/2).'px;}'; } elseif($tmp_handle_height<$tmp_bar_height+2){ $custom_css .= $prefix.' .noUi-horizontal .noUi-handle{top:'.Tools::ps_round(($tmp_bar_height-$tmp_handle_height+2)/2).'px;}'; $custom_css .= $prefix.' .noUi-vertical .noUi-handle{left:'.Tools::ps_round(($tmp_bar_height-$tmp_handle_height+2)/2).'px;}'; } } if(!$bar_height) $bar_height = $range_style ? 10 : 18; if($handle_height){ $custom_css .= $prefix.' .noUi-horizontal .noUi-handle{height:'.$handle_height.'px;}'; $custom_css .= $prefix.' .noUi-vertical .noUi-handle{width:'.$handle_height.'px;}'; if($handle_height>$bar_height-2){ $custom_css .= $prefix.' .st-range.noUi-vertical{margin-left:'.Tools::ps_round(($handle_height-$bar_height-2)/2).'px;margin-right:'.Tools::ps_round(($handle_height-$bar_height-2)/2).'px;}'; $custom_css .= $prefix.' .st-range{margin-top:'.Tools::ps_round(($handle_height-$bar_height-2)/2).'px;margin-bottom:'.Tools::ps_round(($handle_height-$bar_height-2)/2).'px;}'; } } $handle_width = Configuration::get($this->_prefix_st.'HANDLE_WIDTH'); if($handle_width){ $custom_css .= $prefix.' .noUi-horizontal .noUi-handle{width:'.$handle_width.'px;}'; $custom_css .= $prefix.' .noUi-vertical .noUi-handle{height:'.$handle_width.'px;}'; $custom_css .= $prefix.' .noUi-vertical .noUi-handle{top:-'.Tools::ps_round($handle_width/2).'px;}'; $custom_css .= $prefix.' .noUi-horizontal .noUi-handle{left:-'.Tools::ps_round($handle_width/2).'px;}'; $custom_css .= 'html:not([dir=rtl]) '.$prefix.' .noUi-horizontal .noUi-handle{right:-'.Tools::ps_round($handle_width/2).'px;}'; $custom_css .= $prefix.' .st-range.noUi-vertical{margin-top:'.Tools::ps_round($handle_width/2).'px;margin-bottom:'.Tools::ps_round($handle_width/2).'px;}'; $custom_css .= $prefix.' .st-range{margin-left:'.Tools::ps_round($handle_width/2).'px;margin-right:'.Tools::ps_round($handle_width/2).'px;}'; } if($range_style==1 && $handle_width && $handle_height) $custom_css .= $prefix.'.st-noUi-style-1 .noUi-handle{border-radius:'.($handle_width>$handle_height ? $handle_width : $handle_height).'px;}'; $vertical_height = Configuration::get($this->_prefix_st.'VERTICAL_HEIGHT'); $custom_css .= $prefix.' .noUi-vertical{height:'.($vertical_height ?: '200').'px;}'; // if($block_color = Configuration::get($this->_prefix_st.'BLOCK_COLOR')) $custom_css .= '#search_filters{color:'.$block_color.';}'; if($block_link_color = Configuration::get($this->_prefix_st.'BLOCK_LINK_COLOR')) $custom_css .= '.feds_link{color:'.$block_link_color.';}'; if($block_link_active_color = Configuration::get($this->_prefix_st.'BLOCK_LINK_ACTIVE_COLOR')) $custom_css .= '.feds_link:hover, .feds_link.active{color:'.$block_link_active_color.';}'; if($block_bg = Configuration::get($this->_prefix_st.'BLOCK_BG')) $custom_css .= '#search_filters{background-color:'.$block_bg.';}'; if($block_title_color = Configuration::get($this->_prefix_st.'BLOCK_TITLE_COLOR')) $custom_css .= '.feds_block_title{color:'.$block_title_color.';}'; if($block_title_bg = Configuration::get($this->_prefix_st.'BLOCK_TITLE_BG')) $custom_css .= '.feds_block_title{background-color:'.$block_title_bg.';}'; if($font_text_size = Configuration::get($this->_prefix_st.'FONT_TEXT_SIZE')) $custom_css .= '.feds_block_title{font-size: '.$font_text_size.'px;}'; if($toggle_icon_color = Configuration::get($this->_prefix_st.'TOGGLE_ICON_COLOR')) $custom_css .= '.facet_colexp_icons i, .feds_arrow{color:'.$toggle_icon_color.';}'; if($toggle_icon_active_color = Configuration::get($this->_prefix_st.'TOGGLE_ICON_ACTIVE_COLOR')) $custom_css .= '.facet_coled_1 .facet_colexp_icons i, .facet_coled .facet_colexp_icons i, .feds_arrow:hover{color:'.$toggle_icon_active_color.';}'; $block_bottom_margin = Configuration::get($this->_prefix_st.'BLOCK_BOTTOM_MARGIN'); if($block_bottom_margin || $block_bottom_margin===0 || $block_bottom_margin==='0') $custom_css .= '#feds_search_filters #search_filters{margin-bottom:'.$block_bottom_margin.'px;}'; /*if($drop_title_color = Configuration::get($this->_prefix_st.'DROP_TITLE_COLOR')) $custom_css .= '.feds_dropdown_tri{color:'.$drop_title_color.';}'; if($drop_title_bg = Configuration::get($this->_prefix_st.'DROP_TITLE_BG')) $custom_css .= '.feds_dropdown_tri{background-color:'.$drop_title_bg.';}'; */ if($drop_title_active_color = Configuration::get($this->_prefix_st.'DROP_TITLE_ACTIVE_COLOR')) $custom_css .= '.feds_d_open .feds_dropdown_tri{color:'.$drop_title_active_color.';}'; if($drop_title_active_bg = Configuration::get($this->_prefix_st.'DROP_TITLE_ACTIVE_BG')) $custom_css .= '.feds_d_open .feds_dropdown_tri{background-color:'.$drop_title_active_bg.';}'; if($drop_list_background = Configuration::get($this->_prefix_st.'DROP_LIST_BACKGROUND')) $custom_css .= '.feds_dropdown_list .facet_colexp_block{background-color:'.$drop_list_background.';}'; if($overlay_bg = Configuration::get($this->_prefix_st.'LOADING_OVERLAY_BG')){ if(!Validate::isColor($overlay_bg)) $overlay_bg = '#000000'; $overlay_bg_arr = self::hex2rgb($overlay_bg); if(is_array($overlay_bg_arr)) { $overlay_opacity = (float)Configuration::get($this->_prefix_st.'LOADING_OVERLAY_OPACITY'); if($overlay_opacity<0 || $overlay_opacity>1) $overlay_opacity = 0.1; $custom_css .= '.feds_overlay{background-color: rgba('.$overlay_bg_arr[0].','.$overlay_bg_arr[1].','.$overlay_bg_arr[2].','.$overlay_opacity.'); }'; } } if($loading_icon_color = Configuration::get($this->_prefix_st.'LOADING_ICON_COLOR')) $custom_css .= '.feds_overlay_loader{color:'.$loading_icon_color.';}'; if($loading_icon_size = Configuration::get($this->_prefix_st.'LOADING_ICON_SIZE')) $custom_css .= '.feds_overlay_loader{font-size:'.$loading_icon_size.'px;}'; if($block_border_color = Configuration::get($this->_prefix_st.'BLOCK_BORDER_COLOR')) $custom_css .= '#feds_search_filters #search_filters{border-color:'.$block_border_color.';}'; if($block_border_size = Configuration::get($this->_prefix_st.'BLOCK_BORDER_SIZE')) $custom_css .= '#feds_search_filters #search_filters{border-width:'.$block_border_size.'px;}'; if($block_border_radius = Configuration::get($this->_prefix_st.'BLOCK_BORDER_RADIUS')) $custom_css .= '#feds_search_filters #search_filters{border-radius:'.$block_border_radius.'px;}'; if($block_title_border_color = Configuration::get($this->_prefix_st.'BLOCK_TITLE_BORDER_COLOR')) $custom_css .= '.feds_block_title{border-color:'.$block_title_border_color.';}'; if($block_title_border_size = Configuration::get($this->_prefix_st.'BLOCK_TITLE_BORDER_SIZE')) $custom_css .= '.feds_block_title{border-width:'.$block_title_border_size.'px;}'; if($block_title_border_radius = Configuration::get($this->_prefix_st.'BLOCK_TITLE_BORDER_RADIUS')) $custom_css .= '.feds_block_title{border-radius:'.$block_title_border_radius.'px;}'; if($filter_title_color = Configuration::get($this->_prefix_st.'FILTER_TITLE_COLOR')) $custom_css .= '.facet_title, .feds_dropdown_tri, .facet-title-mobile{color:'.$filter_title_color.';}'; if($filter_title_bg = Configuration::get($this->_prefix_st.'FILTER_TITLE_BG')) $custom_css .= '.facet_title, .feds_dropdown_tri, .facet-title-mobile{background-color:'.$filter_title_bg.';}'; if($filter_title_collapsed_color = Configuration::get($this->_prefix_st.'FILTER_TITLE_COLLAPSED_COLOR')){ $custom_css .= '@media only screen and (min-width:768px){.facet_coled_1 .facet_title{color:'.$filter_title_collapsed_color.';}}'; $custom_css .= '@media only screen and (max-width:767px){.facet_coled .facet_title{color:'.$filter_title_collapsed_color.';}}'; } if($filter_title_collapsed_bg = Configuration::get($this->_prefix_st.'FILTER_TITLE_COLLAPSED_BG')){ $custom_css .= '@media only screen and (min-width:768px){.facet_coled_1 .facet_title{background-color:'.$filter_title_collapsed_bg.';}}'; $custom_css .= '@media only screen and (max-width:767px){.facet_coled .facet_title{background-color:'.$filter_title_collapsed_bg.';}}'; } if($filter_title_border_color = Configuration::get($this->_prefix_st.'FILTER_TITLE_BORDER_COLOR')) $custom_css .= '.facet_title, .feds_dropdown_tri{border-color:'.$filter_title_border_color.';}'; //.feds_facet > .facet_title dropdown de shi hou, facet_title_mobile keyi you yiyang de yangshi. if($filter_title_border_radius = Configuration::get($this->_prefix_st.'FILTER_TITLE_BORDER_RADIUS')) $custom_css .= '.facet_title, .feds_dropdown_tri{border-radius:'.$filter_title_border_radius.'px;}'; //.feds_facet > .facet_title dropdown de shi hou, facet_title_mobile keyi you yiyang de yangshi. if($filter_border_color = Configuration::get($this->_prefix_st.'FILTER_BORDER_COLOR')) $custom_css .= '.facet_colexp_block, .feds_facet_x .feds_dropdown_list{border-color:'.$filter_border_color.';}'; if($filter_border_radius = Configuration::get($this->_prefix_st.'FILTER_BORDER_RADIUS')){ $custom_css .= '.facet_colexp_block{border-radius:'.$filter_border_radius.'px;}'; $custom_css .= '@media only screen and (min-width:768px){.feds_facet_x .feds_dropdown_list{border-radius:'.$filter_border_radius.'px;}}'; $custom_css .= '@media only screen and (max-width:767px){.feds_facet_x .facet_colexp_block{border-radius:'.$filter_border_radius.'px;}}'; } if($filter_bottom_margin = Configuration::get($this->_prefix_st.'FILTER_BOTTOM_MARGIN')) $custom_css .= '.facet_colexp_block{margin-bottom:'.$filter_bottom_margin.'px;}'; //feds_facet huibuhui genghao $filter_max_height = Configuration::get($this->_prefix_st.'FILTER_MAX_HEIGHT'); $custom_css .= '#search_filters .feds_facet .facet_with_max_height{max-height:'.($filter_max_height ? $filter_max_height.'px' : 'none').';}'; if($filter_bg = Configuration::get($this->_prefix_st.'FILTER_BG')) $custom_css .= '.facet_colexp_block{background-color:'.$filter_bg.';}'; if($filter_title_size = Configuration::get($this->_prefix_st.'FILTER_TITLE_SIZE')) $custom_css .= '.feds_block_content{font-size:'.$filter_title_size.'px;}'; $arr = $this->getMP(1); foreach ($arr as $mp){ $custom_css .= '.feds_block_title{'.$mp['css_name'].':'.(int)Configuration::get($this->_prefix_st.strtoupper('heading_paddings_'.$mp['id'])).'px;}'; $custom_css .= '.feds_block_content{'.$mp['css_name'].':'.(int)Configuration::get($this->_prefix_st.strtoupper('block_paddings_'.$mp['id'])).'px;}'; $custom_css .= '.facet_colexp_block{'.$mp['css_name'].':'.(int)Configuration::get($this->_prefix_st.strtoupper('filter_paddings_'.$mp['id'])).'px;}'; $custom_css .= '@media only screen and (min-width:768px){.feds_facet_x .feds_dropdown_list{'.$mp['css_name'].':'.(int)Configuration::get($this->_prefix_st.strtoupper('filter_paddings_'.$mp['id'])).'px;}}'; $custom_css .= '@media only screen and (max-width:767px){.feds_facet_x .facet_colexp_block{'.$mp['css_name'].':'.(int)Configuration::get($this->_prefix_st.strtoupper('filter_paddings_'.$mp['id'])).'px;}}'; $custom_css .= '.facet_title, .feds_dropdown_tri{'.$mp['css_name'].':'.(int)Configuration::get($this->_prefix_st.strtoupper('filter_title_paddings_'.$mp['id'])).'px;}'; // $custom_css .= '.feds_button{'.$mp['css_name'].':'.(int)Configuration::get($this->_prefix_st.strtoupper('button_paddings_'.$mp['id'])).'px;}'; $custom_css .= '.feds_active_filters{'.$mp['css_name'].':'.(int)Configuration::get($this->_prefix_st.strtoupper('active_paddings_'.$mp['id'])).'px;}'; } $arr = $this->getMP(2); foreach ($arr as $mp){ $custom_css .= '.facet_title, .feds_dropdown_tri{'.$mp['css_name'].':'.Configuration::get($this->_prefix_st.strtoupper('filter_title_border_sizes_'.$mp['id'])).'px;}'; //.feds_facet > .facet_title dropdown de shi hou, facet_title_mobile keyi you yiyang de yangshi. $custom_css .= '.facet_colexp_block{'.$mp['css_name'].':'.Configuration::get($this->_prefix_st.strtoupper('filter_border_sizes_'.$mp['id'])).'px;}'; $custom_css .= '@media only screen and (min-width:768px){.feds_facet_x .feds_dropdown_list{'.$mp['css_name'].':'.Configuration::get($this->_prefix_st.strtoupper('filter_border_sizes_'.$mp['id'])).'px;}}'; $custom_css .= '@media only screen and (max-width:767px){.feds_facet_x .facet_colexp_block{'.$mp['css_name'].':'.Configuration::get($this->_prefix_st.strtoupper('filter_border_sizes_'.$mp['id'])).'px;}}'; } if($font_filter_title_trans = Configuration::get($this->_prefix_st.'FONT_FILTER_TITLE_TRANS')) $custom_css .= '.facet_title_text, .feds_dropdown_tri .stfeds_flex_child{text-transform: '.self::$textTransform[(int)$font_filter_title_trans]['name'].';}'; if($font_filter_title_size = Configuration::get($this->_prefix_st.'FONT_FILTER_TITLE_SIZE')) $custom_css .= '.facet_title_text, .feds_dropdown_tri .stfeds_flex_child{font-size: '.$font_filter_title_size.'px;}'; // if($button_color = Configuration::get($this->_prefix_st.'BUTTON_COLOR')) $custom_css .= '.feds_button{color:'.$button_color.';}'; if($button_bg = Configuration::get($this->_prefix_st.'BUTTON_BG')) $custom_css .= '.feds_button{background-color:'.$button_bg.';}'; if($button_active_color = Configuration::get($this->_prefix_st.'BUTTON_ACTIVE_COLOR')) $custom_css .= '.feds_button:hover, .feds_button.active{color:'.$button_active_color.';}'; if($button_active_bg = Configuration::get($this->_prefix_st.'BUTTON_ACTIVE_BG')) $custom_css .= '.feds_button:hover, .feds_button.active{background-color:'.$button_active_bg.';}'; if($button_border_color = Configuration::get($this->_prefix_st.'BUTTON_BORDER_COLOR')) $custom_css .= '.feds_button{border-color:'.$button_border_color.';}'; if($button_active_border_color = Configuration::get($this->_prefix_st.'BUTTON_ACTIVE_BORDER_COLOR')) $custom_css .= '.feds_button:hover, .feds_button.active{border-color:'.$button_active_border_color.';}'; if($button_border_size = Configuration::get($this->_prefix_st.'BUTTON_BORDER_SIZE')) $custom_css .= '.feds_button{border-width:'.$button_border_size.'px;}'; if($button_border_radius = Configuration::get($this->_prefix_st.'BUTTON_BORDER_RADIUS')) $custom_css .= '.feds_button{border-radius:'.$button_border_radius.'px;}'; if($button_text_size = Configuration::get($this->_prefix_st.'BUTTON_TEXT_SIZE')) $custom_css .= '.feds_button{font-size:'.$button_text_size.'px;}'; /*if($button_min_width = Configuration::get($this->_prefix_st.'BUTTON_MIN_WIDTH')) $custom_css .= '.feds_button{min-width:'.$button_min_width.'px;}'; */ if($checkbox_bg = Configuration::get($this->_prefix_st.'CHECKBOX_BG')) $custom_css .= '.feds_custom-input-box .feds_custom-input-item.feds_custom-input-checkbox, .feds_custom-input-box .feds_custom-input-item.feds_custom-input-radio{background-color:'.$checkbox_bg.';}'; if($checkbox_tick_color = Configuration::get($this->_prefix_st.'CHECKBOX_TICK_COLOR')) $custom_css .= '.feds_custom-input-box input:checked+.feds_custom-input-item i{color:'.$checkbox_tick_color.';}'; if($checkbox_active_bg = Configuration::get($this->_prefix_st.'CHECKBOX_ACTIVE_BG')) $custom_css .= '.feds_custom-input-box input:checked+.feds_custom-input-item.feds_custom-input-checkbox,.feds_custom-input-box:hover .feds_custom-input-item.feds_custom-input-checkbox,.feds_custom-input-box input:checked+.feds_custom-input-item.feds_custom-input-radio,.feds_custom-input-box:hover .feds_custom-input-item.feds_custom-input-radio{background-color:'.$checkbox_active_bg.';}'; $checkbox_border_size = (int)Configuration::get($this->_prefix_st.'CHECKBOX_BORDER_SIZE'); $custom_css .= '.feds_custom-input-box .feds_custom-input-item.feds_custom-input-checkbox,.feds_custom-input-box .feds_custom-input-item.feds_custom-input-radio{border-width:'.$checkbox_border_size.'px;}'; if(!$checkbox_border_size) $custom_css .= '.feds_custom-input-box .feds_custom-input-item.feds_custom-input-checkbox,.feds_custom-input-box .feds_custom-input-item.feds_custom-input-radio{line-height:15px;}';//default line height when border is 0 if($checkbox_border_color = Configuration::get($this->_prefix_st.'CHECKBOX_BORDER_COLOR')) $custom_css .= '.feds_custom-input-box .feds_custom-input-item.feds_custom-input-checkbox,.feds_custom-input-box .feds_custom-input-item.feds_custom-input-radio{border-color:'.$checkbox_border_color.';}'; if($checkbox_tick_size = Configuration::get($this->_prefix_st.'CHECKBOX_TICK_SIZE')) { $custom_css .= '.feds_custom-input-box .feds_custom-input-item i{font-size:'.$checkbox_tick_size.'px;}'; $tick_box_size = round($checkbox_tick_size*1.2); $custom_css .= '.feds_custom-input-box .feds_custom-input-item.feds_custom-input-checkbox,.feds_custom-input-box .feds_custom-input-item.feds_custom-input-radio{height:'.$tick_box_size.'px;line-height:'.($tick_box_size-2*$checkbox_border_size).'px;width:'.$tick_box_size.'px;}'; $custom_css .= '.feds_custom-input-box .feds_custom-input-default{height:'.$tick_box_size.'px;width:'.$tick_box_size.'px;}'; } if($checkbox_color = Configuration::get($this->_prefix_st.'CHECKBOX_COLOR')) $custom_css .= '.facet_type_checkbox .feds_link{color:'.$checkbox_color.';}'; if($checkbox_active_color = Configuration::get($this->_prefix_st.'CHECKBOX_ACTIVE_COLOR')) $custom_css .= '.facet_type_checkbox .feds_link:hover, .facet_type_checkbox .feds_link.active{color:'.$checkbox_active_color.';}'; // if($af_color = Configuration::get($this->_prefix_st.'AF_COLOR')) $custom_css .= '.feds_active_filters .feds_link{color:'.$af_color.';}'; if($af_active_color = Configuration::get($this->_prefix_st.'AF_ACTIVE_COLOR')) $custom_css .= '.feds_active_filters .feds_link:hover, .feds_active_filters .feds_link.active{color:'.$af_active_color.';}'; if($af_bg = Configuration::get($this->_prefix_st.'AF_BG')) $custom_css .= '.feds_active_filters .feds_link{background-color:'.$af_bg.';}'; if($af_active_bg = Configuration::get($this->_prefix_st.'AF_ACTIVE_BG')) $custom_css .= '.feds_active_filters .feds_link:hover, .feds_active_filters .feds_link.active{background-color:'.$af_active_bg.';}'; if($af_border_size = Configuration::get($this->_prefix_st.'AF_BORDER_SIZE')) $custom_css .= '.feds_active_filters .feds_link{border-width:'.$af_border_size.'px;text-decoration:none;padding:2px 3px;}'; if($af_border_color = Configuration::get($this->_prefix_st.'AF_BORDER_COLOR')) $custom_css .= '.feds_active_filters .feds_link{border-color:'.$af_border_color.';}'; if($af_border_style = Configuration::get($this->_prefix_st.'AF_BORDER_STYLE')) $custom_css .= '.feds_active_filters .feds_link{border-style:'.($af_border_style==2 ? 'dotted' : 'dashed').';}'; // $color_box_border_size = (int)Configuration::get($this->_prefix_st.'COLOR_BOX_BORDER_SIZE'); $custom_css .= '.feds_custom-input-box .feds_custom-input-item.feds_custom-input-color{border-width:'.$color_box_border_size.'px;}'; if(!$color_box_border_size) $custom_css .= '.feds_custom-input-box .feds_custom-input-item.feds_custom-input-color{line-height:15px;}';//default line height when border is 0 if($color_box_border_radius = Configuration::get($this->_prefix_st.'COLOR_BOX_BORDER_RADIUS')) $custom_css .= '.feds_custom-input-box .feds_custom-input-item.feds_custom-input-color{border-radius:'.$color_box_border_radius.'px;}'; if($color_box_border_color = Configuration::get($this->_prefix_st.'COLOR_BOX_BORDER_COLOR')) $custom_css .= '.feds_custom-input-box .feds_custom-input-item.feds_custom-input-color{border-color:'.$color_box_border_color.';}'; if($color_box_border_hover_color = Configuration::get($this->_prefix_st.'COLOR_BOX_BORDER_HOVER_COLOR')) $custom_css .= '.feds_custom-input-box input:checked+.feds_custom-input-item.feds_custom-input-color,.feds_custom-input-box:hover .feds_custom-input-item.feds_custom-input-color{border-color:'.$color_box_border_hover_color.';}'; if($color_box_width = Configuration::get($this->_prefix_st.'COLOR_BOX_WIDTH')){ $custom_css .= '.feds_custom-input-box .feds_custom-input-item.feds_custom-input-color{width:'.$color_box_width.'px;}'; $custom_css .= '.feds_custom-input-box .feds_custom-input-yanse{width:'.$color_box_width.'px;}'; } if($color_box_height = Configuration::get($this->_prefix_st.'COLOR_BOX_HEIGHT')){ $custom_css .= '.feds_custom-input-box .feds_custom-input-item.feds_custom-input-color{height:'.$color_box_height.'px;line-height:'.($color_box_height-2*$color_box_border_size).'px;}'; $custom_css .= '.feds_custom-input-box .feds_custom-input-yanse{height:'.$color_box_height.'px;}'; } if($drop_down_width = Configuration::get($this->_prefix_st.'DROP_DOWN_WIDTH')) $custom_css .= '.feds_dropdown_list{min-width:'.$drop_down_width.'px;}'; if($showmore_blocks_color = Configuration::get($this->_prefix_st.'SHOWMORE_BLOCKS_COLOR')) $custom_css .= '.feds_facet_showmore .stfeds_flex_container{color:'.$showmore_blocks_color.';}'; if($showmore_blocks_bg = Configuration::get($this->_prefix_st.'SHOWMORE_BLOCKS_BG')) $custom_css .= '.feds_facet_showmore .stfeds_flex_container{background-color:'.$showmore_blocks_bg.';}'; if($showmore_blocks_active_color = Configuration::get($this->_prefix_st.'SHOWMORE_BLOCKS_ACTIVE_COLOR')) $custom_css .= '.feds_facet_showmore .stfeds_flex_container:hover{color:'.$showmore_blocks_active_color.';}'; if($showmore_blocks_active_bg = Configuration::get($this->_prefix_st.'SHOWMORE_BLOCKS_ACTIVE_BG')) $custom_css .= '.feds_facet_showmore .stfeds_flex_container:hover{background-color:'.$showmore_blocks_active_bg.';}'; if($sidebar_close_color = Configuration::get($this->_prefix_st.'SIDEBAR_CLOSE_COLOR')) $custom_css .= '.feds_offcanvas_times{color:'.$sidebar_close_color.';}'; if($sidebar_close_active_color = Configuration::get($this->_prefix_st.'SIDEBAR_CLOSE_ACTIVE_COLOR')) $custom_css .= '.feds_offcanvas_times:hover{color:'.$sidebar_close_active_color.';}'; if($sidebar_bg = Configuration::get($this->_prefix_st.'SIDEBAR_BG')) $custom_css .= '.feds_offcanvas_content{background-color:'.$sidebar_bg.';}'; if($overlay_bg = Configuration::get($this->_prefix_st.'SIDEBAR_OVERLAY_BG')){ if(!Validate::isColor($overlay_bg)) $overlay_bg = '#000000'; $overlay_bg_arr = self::hex2rgb($overlay_bg); if(is_array($overlay_bg_arr)) { $overlay_opacity = (float)Configuration::get($this->_prefix_st.'SIDEBAR_OVERLAY_OPACITY'); if($overlay_opacity<0 || $overlay_opacity>1) $overlay_opacity = 0.1; $custom_css .= '.feds_offcanvas_background{background-color: rgba('.$overlay_bg_arr[0].','.$overlay_bg_arr[1].','.$overlay_bg_arr[2].','.$overlay_opacity.'); }'; } } if($sidebar_width = Configuration::get($this->_prefix_st.'SIDEBAR_WIDTH')){ $custom_css .= '.feds_offcanvas_content{width:'.$sidebar_width.'px;}'; $custom_css .= '.feds_offcanvas_times{left:'.$sidebar_width.'px;}'; $custom_css .= '.feds_open #feds_overlay.feds_overlay_center{width:'.$sidebar_width.'px;}'; } if($showmore_btn_color = Configuration::get($this->_prefix_st.'SHOWMORE_BTN_COLOR')) $custom_css .= '.feds_showmore_button{color:'.$showmore_btn_color.';}'; if($showmore_btn_active_color = Configuration::get($this->_prefix_st.'SHOWMORE_BTN_ACTIVE_COLOR')) $custom_css .= '.feds_showmore_button:hover{color:'.$showmore_btn_active_color.';}'; if($select_color=Configuration::get($this->_prefix_st.'SELECT_COLOR')) $custom_css .= '.feds_block_content .form-control-select{color:'.$select_color.';}'; if($select_actve_color=Configuration::get($this->_prefix_st.'SELECT_ACTVE_COLOR')) $custom_css .= '.feds_block_content .form-control-select:focus{color:'.$select_actve_color.';}'; if($select_bg=Configuration::get($this->_prefix_st.'SELECT_BG')) $custom_css .= '.feds_block_content .form-control-select{background-color:'.$select_bg.';}'; if($select_actve_bg=Configuration::get($this->_prefix_st.'SELECT_ACTVE_BG')) $custom_css .= '.feds_block_content .form-control-select:focus{background-color:'.$select_actve_bg.';}'; if($select_border_size=Configuration::get($this->_prefix_st.'SELECT_BORDER_SIZE')) $custom_css .= '.feds_block_content .form-control-select{border-size:'.$select_border_size.'px;}'; if($select_border_color=Configuration::get($this->_prefix_st.'SELECT_BORDER_COLOR')) $custom_css .= '.feds_block_content .form-control-select{border-color:'.$select_border_color.';}'; if($select_active_border_color=Configuration::get($this->_prefix_st.'SELECT_ACTIVE_BORDER_COLOR')) $custom_css .= '.feds_block_content .form-control-select:focus{border-color:'.$select_active_border_color.';}'; if($sidebar_btn_color=Configuration::get($this->_prefix_st.'SIDEBAR_BTN_COLOR')) $custom_css .= '.feds_offcanvas_btn a{color:'.$sidebar_btn_color.';}'; if($sidebar_btn_bg=Configuration::get($this->_prefix_st.'SIDEBAR_BTN_BG')) $custom_css .= '.feds_offcanvas_btn a{background-color:'.$sidebar_btn_bg.';}'; if($sidebar_btn_hover_color=Configuration::get($this->_prefix_st.'SIDEBAR_BTN_HOVER_COLOR')) $custom_css .= '.feds_offcanvas_btn a:hover{color:'.$sidebar_btn_hover_color.';}'; if($sidebar_btn_hover_bg=Configuration::get($this->_prefix_st.'SIDEBAR_BTN_HOVER_BG')) $custom_css .= '.feds_offcanvas_btn a:hover{background-color:'.$sidebar_btn_hover_bg.';}'; if($img_border_size=Configuration::get($this->_prefix_st.'IMG_BORDER_SIZE')) $custom_css .= '.facet_type_image .feds_link{border-width:'.$img_border_size.'px;}'; if($img_border_radius=Configuration::get($this->_prefix_st.'IMG_BORDER_RADIUS')) $custom_css .= '.facet_type_image .feds_link{border-radius:'.$img_border_radius.'px;}'; if($img_border_color=Configuration::get($this->_prefix_st.'IMG_BORDER_COLOR')) $custom_css .= '.facet_type_image .feds_link{border-color:'.$img_border_color.';}'; if($img_border_hover_color=Configuration::get($this->_prefix_st.'IMG_BORDER_HOVER_COLOR')) $custom_css .= '.facet_type_image .feds_link:hover,.facet_type_image .feds_link.active{border-color:'.$img_border_hover_color.';}'; // if($trigger_color = Configuration::get($this->_prefix_st.'TRIGGER_COLOR')) $custom_css .= '.feds_offcanvas_tri{color:'.$trigger_color.';}'; if($trigger_active_color = Configuration::get($this->_prefix_st.'TRIGGER_ACTIVE_COLOR')) $custom_css .= '.feds_offcanvas_tri:hover, .feds_offcanvas_tri.active{color:'.$trigger_active_color.';}'; if($trigger_bg = Configuration::get($this->_prefix_st.'TRIGGER_BG')) $custom_css .= '.feds_offcanvas_tri{background-color:'.$trigger_bg.';}'; if($trigger_active_bg = Configuration::get($this->_prefix_st.'TRIGGER_ACTIVE_BG')) $custom_css .= '.feds_offcanvas_tri:hover, .feds_offcanvas_tri.active{background-color:'.$trigger_active_bg.';}'; $trigger_border_size = (int)Configuration::get($this->_prefix_st.'TRIGGER_BORDER_SIZE'); if($trigger_border_size) $custom_css .= '.feds_offcanvas_tri{border-width:'.$trigger_border_size.'px;}'; if($trigger_border_color = Configuration::get($this->_prefix_st.'TRIGGER_BORDER_COLOR')) $custom_css .= '.feds_offcanvas_tri{border-color:'.$trigger_border_color.';}'; if($trigger_border_style = Configuration::get($this->_prefix_st.'TRIGGER_BORDER_STYLE')) $custom_css .= '.feds_offcanvas_tri{border-style:'.($trigger_border_style==2 ? 'dotted' : 'dashed').';}'; if($trigger_size = Configuration::get($this->_prefix_st.'TRIGGER_SIZE')) $custom_css .= '.feds_offcanvas_tri{font-size:'.$trigger_size.'px;}'; if($trigger_width = Configuration::get($this->_prefix_st.'TRIGGER_WIDTH')) $custom_css .= '.feds_offcanvas_tri{max-width:'.$trigger_width.'px;}'; if($trigger_height = Configuration::get($this->_prefix_st.'TRIGGER_HEIGHT')) $custom_css .= '.feds_offcanvas_tri{height:'.$trigger_height.'px;line-height:'.($trigger_height-2*$trigger_border_size).'px;}'; // $fontText = $fontFilterTitle = ''; $fontTextWeight = $fontFilterTitleWeight = ''; $fontTextStyle = $fontFilterTitleStyle = ''; if($fontTextString = Configuration::get($this->_prefix_st.'FONT_TEXT')) { preg_match_all('/^([^:]+):?(\d*)([a-z]*)$/', $fontTextString, $fontTextArr); $fontText = $fontTextArr[1][0]; $fontTextArr[2][0] && $fontTextWeight = 'font-weight:'.$fontTextArr[2][0].';'; $fontTextArr[3][0] && $fontTextStyle = 'font-style:'.$fontTextArr[3][0].';'; } if($fontFilterTitleString = Configuration::get($this->_prefix_st.'FONT_FILTER_TITLE')) { preg_match_all('/^([^:]+):?(\d*)([a-z]*)$/', $fontFilterTitleString, $fontFilterTitleArr); $fontFilterTitle = $fontFilterTitleArr[1][0]; $fontFilterTitleArr[2][0] && $fontFilterTitleWeight = 'font-weight:'.$fontFilterTitleArr[2][0].';'; $fontFilterTitleArr[3][0] && $fontFilterTitleStyle = 'font-style:'.$fontFilterTitleArr[3][0].';'; } if($fontText) $custom_css .= '.feds_block_title{'.($fontText != $this->_font_inherit ? 'font-family:'.(preg_match("/[\d\s_]/", $fontText) ? '"'.$fontText.'"' : $fontText).', Tahoma, sans-serif, Arial;' : '').$fontTextWeight.$fontTextStyle.'}'; if($font_text_trans = Configuration::get($this->_prefix_st.'FONT_TEXT_TRANS')) $custom_css .= '.feds_block_title{text-transform: '.self::$textTransform[(int)$font_text_trans]['name'].';}'; if($fontFilterTitle) $custom_css .= '.facet_title_text, .feds_dropdown_tri span{'.($fontFilterTitle != $this->_font_inherit ? 'font-family:'.(preg_match("/[\d\s_]/", $fontFilterTitle) ? '"'.$fontFilterTitle.'"' : $fontFilterTitle).', Tahoma, sans-serif, Arial;' : '').$fontFilterTitleWeight.$fontFilterTitleStyle.'}'; if($fontFilterTitleWeight) $custom_css .= '.feds_dropdown_tri .feds_arrow:before{'.$fontFilterTitleWeight.'}'; $sql = new DbQuery(); $sql->select('*') ->from('st_search_facet_item'); $res = Db::getInstance()->executeS($sql); foreach ($res as $v) { if($v['min_width']){ // $custom_css .= '.feds_facet_'.$v['id_st_search_filter'].' .feds_filter_'.$v['id_st_search_facet_item'].' .feds_button{min-width:'.$v['min_width'].'px;}'; $custom_css .= '.feds_facet_'.$v['id_st_search_filter'].' .feds_filter_'.$v['id_st_search_facet_item'].' .filter_zhuangtai{min-width:'.$v['min_width'].'px;}'; } if($v['bg']) $custom_css .= '.feds_facet_'.$v['id_st_search_filter'].' .feds_filter_'.$v['id_st_search_facet_item'].'{background-color:'.$v['bg'].';}'; if($v['img_width']) $custom_css .= '.feds_facet_'.$v['id_st_search_filter'].' .feds_filter_'.$v['id_st_search_facet_item'].' .feds_image_filter_img{width:'.$v['img_width'].'px;}'; if($v['bar_bg_left']){ $custom_css .= '.feds_facet_'.$v['id_st_search_filter'].' .feds_filter_'.$v['id_st_search_facet_item'].' .noUi-connect{background-color:'.$v['bar_bg_left'].';}'; if($v['bar_bg_right']){ $custom_css .= '.feds_facet_'.$v['id_st_search_filter'].' .feds_filter_'.$v['id_st_search_facet_item'].' .noUi-connect{background: -webkit-gradient(linear,left top,right top,color-stop(0%,'.$v['bar_bg_left'].'),color-stop(100%,'.$v['bar_bg_right'].')); background: -webkit-linear-gradient(left,'.$v['bar_bg_left'].' 0%,'.$v['bar_bg_right'].' 100%);}'; } } if($v['text_align']) $custom_css .= '.feds_facet_'.$v['id_st_search_filter'].' .feds_filter_'.$v['id_st_search_facet_item'].' .feds_link{text-align:left;}'; if($v['tb_mar']){ $custom_css .= '.feds_facet_'.$v['id_st_search_filter'].' .feds_filter_'.$v['id_st_search_facet_item'].' .filter_zhuangtai{margin-top:'.$v['tb_mar'].'px;margin-bottom:'.$v['tb_mar'].'px;}'; $custom_css .= '.feds_facet_'.$v['id_st_search_filter'].' .feds_filter_'.$v['id_st_search_facet_item'].' .feds_select{margin-top:'.$v['tb_mar'].'px;margin-bottom:'.$v['tb_mar'].'px;}'; } if($v['lr_mar']){ $custom_css .= '.feds_facet_'.$v['id_st_search_filter'].' .feds_filter_'.$v['id_st_search_facet_item'].' .filter_zhuangtai{margin-left:'.$v['lr_mar'].'px;margin-right:'.$v['lr_mar'].'px;}'; $custom_css .= '.feds_facet_'.$v['id_st_search_filter'].' .feds_filter_'.$v['id_st_search_facet_item'].' .feds_select{margin-left:'.$v['lr_mar'].'px;margin-right:'.$v['lr_mar'].'px;}'; } if($v['tb_pad']) $custom_css .= '.feds_facet_'.$v['id_st_search_filter'].' .feds_filter_'.$v['id_st_search_facet_item'].' .feds_link, .feds_facet_'.$v['id_st_search_filter'].' .feds_filter_'.$v['id_st_search_facet_item'].' .feds_showmore_button{padding-top:'.$v['tb_pad'].'px;padding-bottom:'.$v['tb_pad'].'px;}'; if($v['lr_pad']) $custom_css .= '.feds_facet_'.$v['id_st_search_filter'].' .feds_filter_'.$v['id_st_search_facet_item'].' .feds_link, .feds_facet_'.$v['id_st_search_filter'].' .feds_filter_'.$v['id_st_search_facet_item'].' .feds_showmore_button{padding-left:'.$v['lr_pad'].'px;padding-right:'.$v['lr_pad'].'px;}'; if($v['pad'] || $v['pad']===0 || $v['pad']==='0') $custom_css .= '.feds_facet_'.$v['id_st_search_filter'].' .feds_filter_'.$v['id_st_search_facet_item'].'{padding:'.$v['pad'].'px;}'; if($v['border'] || $v['border']===0 || $v['border']==='0') $custom_css .= '.feds_facet_'.$v['id_st_search_filter'].' .feds_filter_'.$v['id_st_search_facet_item'].' .feds_link{border-width:'.$v['border'].'px;}'; } // $custom_css = preg_replace('/\s\s+/', ' ', $custom_css); if ($css = Configuration::get($this->_prefix_st.'CUSTOM_CSS')) $custom_css .= html_entity_decode(str_replace('¤', '\\', $css)); $this->smarty->assign('stfacetdsearch', array( 'custom_css' => html_entity_decode($custom_css), )); } $mobile_detect = $this->context->getMobileDetect(); $mobile_device = $mobile_detect->isMobile() || $mobile_detect->isTablet(); $js_val = array( 'with_inputs' => Configuration::get($this->_prefix_st.'WITH_INPUTS'), 'tooltips' => Configuration::get($this->_prefix_st.'TOOLTIPS'), 'price_step' => (float)Configuration::get($this->_prefix_st.'PRICE_STEP'), 'weight_step' => (float)Configuration::get($this->_prefix_st.'WEIGHT_STEP'), 'drop_down' => (int)Configuration::get($this->_prefix_st.'DROP_DOWN'), 'loading_effect' => (int)Configuration::get($this->_prefix_st.'LOADING_EFFECT'), 'product_list_selector' => Configuration::get($this->_prefix_st.'PRODUCT_LIST_SELECTOR'), 'magic' => Configuration::get($this->_prefix_st.'MAGIC'), 'is_mobile_device' => $mobile_device, 'sample' => array( 'price' => Tools::displayPrice(12345678.123), 'weight' => Tools::displayNumber(Tools::ps_round(12345678.123456, Configuration::get($this->_prefix_st.'W_DECIMAL'))).Configuration::get('PS_WEIGHT_UNIT'), ), ); Media::addJsDef(array('stfacetdsearch' => $js_val)); $theme_font = array(); $theme_font[] = Configuration::get($this->_prefix_st.'FONT_TEXT'); $theme_font[] = Configuration::get($this->_prefix_st.'FONT_FILTER_TITLE'); $font_latin_support = Configuration::get($this->_prefix_st.'FONT_LATIN_SUPPORT'); $font_cyrillic_support = Configuration::get($this->_prefix_st.'FONT_CYRILLIC_SUPPORT'); $font_vietnamese = Configuration::get($this->_prefix_st.'FONT_VIETNAMESE'); $font_greek_support = Configuration::get($this->_prefix_st.'FONT_GREEK_SUPPORT'); $font_arabic_support = Configuration::get($this->_prefix_st.'FONT_ARABIC_SUPPORT'); $font_support = ($font_latin_support || $font_cyrillic_support || $font_vietnamese || $font_greek_support || $font_arabic_support) ? '&subset=' : ''; $font_latin_support && $font_support .= 'latin,latin-ext,'; $font_cyrillic_support && $font_support .= 'cyrillic,cyrillic-ext,'; $font_vietnamese && $font_support .= 'vietnamese,'; $font_greek_support && $font_support .= 'greek,greek-ext,'; $font_arabic_support && $font_support .= 'arabic,'; $theme_font = array_unique($theme_font); if(is_array($theme_font) && count($theme_font)) { $fonts = array(); foreach($theme_font as $v) { $arr = explode(':', $v); if(!isset($arr[0]) || !$arr[0] || $arr[0] == $this->_font_inherit || in_array($arr[0], $this->systemFonts)) continue; $gf_key = preg_replace('/\s/iS','_',$arr[0]); if (isset($arr[1]) && !in_array($arr[1], $this->googleFonts[$gf_key]['variants'])) $v = $arr[0]; $fonts[] = str_replace(' ', '+', $v); } if ($fonts) { $this->context->controller->registerStylesheet('stfacetdsearch-google-fonts', $this->context->link->protocol_content."fonts.googleapis.com/css?family=".implode('|', $fonts).($font_support ? rtrim($font_support,',') : ''), ['server' => 'remote']); } } return $this->fetch('module:stfacetedsearch/views/templates/hook/header.tpl', $this->getCacheId()); } public static function hex2rgb($hex) { $hex = str_replace("#", "", $hex); if(strlen($hex) == 3) { $r = hexdec(substr($hex,0,1).substr($hex,0,1)); $g = hexdec(substr($hex,1,1).substr($hex,1,1)); $b = hexdec(substr($hex,2,1).substr($hex,2,1)); } else { $r = hexdec(substr($hex,0,2)); $g = hexdec(substr($hex,2,2)); $b = hexdec(substr($hex,4,2)); } $rgb = array($r, $g, $b); return $rgb; } /** * {@inheritdoc} */ public function renderWidget($hookName, array $configuration) { $this->smarty->assign($this->getWidgetVariables($hookName, $configuration)); return $this->fetch( 'module:stfacetedsearch/views/templates/hook/stfacetedsearch.tpl' ); } /** * {@inheritdoc} */ public function getWidgetVariables($hookName, array $configuration) { return []; } public function getManufacturers($active = false) { return Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS(' SELECT m.*, m.`id_manufacturer` as id, ml.`description`, ml.`short_description` FROM `' . _DB_PREFIX_ . 'manufacturer` m' . Shop::addSqlAssociation('manufacturer', 'm') . 'INNER JOIN `' . _DB_PREFIX_ . 'manufacturer_lang` ml ON (m.`id_manufacturer` = ml.`id_manufacturer` AND ml.`id_lang` = ' . (int) $this->context->language->id . ')' . 'WHERE 1 ' . ($active ? 'AND m.`active` = 1 ' : '')); } public function initDropListGroup() { $this->fields_form[7]['form']['input']['filters_per']['name'] = $this->BuildDropListGroup($this->findCateProPer(1),1,4); } public function BuildDropListGroup($group,$start=1,$end=6) { if(!is_array($group) || !count($group)) return false; $html = '
'; foreach($group AS $key => $k) { if($key==3) $html .= '
'; $html .= '
'. '
'; } return $html.'
'; } public function findCateProPer($k=null) { $proper = array( 1 => array( array( 'id' => 'filters_per_xl', 'label' => $this->l('Extra large devices'), 'tooltip' => $this->l('Desktops (>1200px)'), ), array( 'id' => 'filters_per_lg', 'label' => $this->l('Large devices'), 'tooltip' => $this->l('Desktops (>992px)'), ), array( 'id' => 'filters_per_md', 'label' => $this->l('Medium devices'), 'tooltip' => $this->l('Desktops (>768px)'), ), ), ); return ($k!==null && isset($proper[$k])) ? $proper[$k] : $proper; } public static function setFacetedSearchFilters($facetedSearchFilters) { self::$facetedSearchFilters = $facetedSearchFilters; } public static function getFacetedSearchFilters() { return self::$facetedSearchFilters; } }