diff --git a/modules/blocklayered/blocklayered-ajax-back.php b/modules/blocklayered/blocklayered-ajax-back.php deleted file mode 100644 index 427ca792d..000000000 --- a/modules/blocklayered/blocklayered-ajax-back.php +++ /dev/null @@ -1,53 +0,0 @@ - -* @copyright 2007-2013 PrestaShop SA - -* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) -* International Registred Trademark & Property of PrestaShop SA -*/ - -/* Getting cookie or logout */ -include(dirname(__FILE__).'/../../config/config.inc.php'); -require_once(dirname(__FILE__).'/../../init.php'); - -if (substr(Tools::encrypt('blocklayered/index'),0,10) != Tools::getValue('layered_token') || !Module::isInstalled('blocklayered')) - die('Bad token'); - -if (Tools::getValue('admin_dir', false)) -{ - define('_PS_ADMIN_DIR_', base64_decode(Tools::getValue('admin_dir'))); - define('_PS_BO_ALL_THEMES_DIR_', _PS_ADMIN_DIR_.'/themes/'); -} - - -include(dirname(__FILE__).'/blocklayered.php'); - -$category_box = Tools::getValue('categoryBox'); - - -/* Clean categoryBox before use */ -if (is_array($category_box)) - foreach ($category_box AS &$value) - $value = (int)$value; - -$blockLayered = new BlockLayered(); -echo $blockLayered->ajaxCallBackOffice($category_box, Tools::getValue('id_layered_filter')); diff --git a/modules/blocklayered/blocklayered.php b/modules/blocklayered/blocklayered.php index 3ec7fa4b1..b18dcdf5d 100644 --- a/modules/blocklayered/blocklayered.php +++ b/modules/blocklayered/blocklayered.php @@ -249,9 +249,587 @@ class BlockLayered extends Module KEY `id_attribute` (`id_attribute`) ) ENGINE='._MYSQL_ENGINE_.' DEFAULT CHARSET=utf8;'); } + + //ATTRIBUTES GROUP + public function hookAfterSaveAttributeGroup($params) + { + if (!$params['id_attribute_group'] || Tools::getValue('layered_indexable') === false) + return; + + Db::getInstance()->execute( + 'DELETE FROM '._DB_PREFIX_.'layered_indexable_attribute_group + WHERE `id_attribute_group` = '.(int)$params['id_attribute_group'] + ); + Db::getInstance()->execute( + 'DELETE FROM '._DB_PREFIX_.'layered_indexable_attribute_group_lang_value + WHERE `id_attribute_group` = '.(int)$params['id_attribute_group'] + ); + + Db::getInstance()->execute( + 'INSERT INTO '._DB_PREFIX_.'layered_indexable_attribute_group + VALUES ('.(int)$params['id_attribute_group'].', '.(int)Tools::getValue('layered_indexable').')' + ); + + + foreach (Language::getLanguages(false) as $language) + { + $seo_url = Tools::getValue('url_name_'.(int)$language['id_lang']); + + if(empty($seo_url)) + $seo_url = Tools::getValue('name_'.(int)$language['id_lang']); + + Db::getInstance()->execute( + 'INSERT INTO '._DB_PREFIX_.'layered_indexable_attribute_group_lang_value + VALUES ( + '.(int)$params['id_attribute_group'].', '.(int)$language['id_lang'].', + \''.pSQL(Tools::link_rewrite($seo_url)).'\', + \''.pSQL(Tools::getValue('meta_title_'.(int)$language['id_lang']), true).'\' + )' + ); + } + } - /** - * + public function hookAfterDeleteAttributeGroup($params) + { + if (!$params['id_attribute_group']) + return; + + Db::getInstance()->execute( + 'DELETE FROM '._DB_PREFIX_.'layered_indexable_attribute_group + WHERE `id_attribute_group` = '.(int)$params['id_attribute_group'] + ); + Db::getInstance()->execute( + 'DELETE FROM '._DB_PREFIX_.'layered_indexable_attribute_group_lang_value + WHERE `id_attribute_group` = '.(int)$params['id_attribute_group'] + ); + } + + public function hookPostProcessAttributeGroup($params) + { + $errors = array(); + + foreach (Language::getLanguages(false) as $language) + { + $id_lang = $language['id_lang']; + + if (Tools::getValue('url_name_'.$id_lang)) + if (Tools::link_rewrite(Tools::getValue('url_name_'.$id_lang)) != strtolower(Tools::getValue('url_name_'.$id_lang))) + $params['errors'][] = Tools::displayError(sprintf($this->l('"%s" is not a valid url'), + Tools::getValue('url_name_'.$id_lang))); + } + } + + public function hookAttributeGroupForm($params) + { + $values = array(); + $is_indexable = Db::getInstance(_PS_USE_SQL_SLAVE_)->getValue( + 'SELECT `indexable` + FROM '._DB_PREFIX_.'layered_indexable_attribute_group + WHERE `id_attribute_group` = '.(int)$params['id_attribute_group'] + ); + + if ($is_indexable === false) + $is_indexable = true; + + if ($result = Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS( + 'SELECT `url_name`, `meta_title`, `id_lang` FROM '._DB_PREFIX_.'layered_indexable_attribute_group_lang_value + WHERE `id_attribute_group` = '.(int)$params['id_attribute_group'] + )) + foreach ($result as $data) + $values[$data['id_lang']] = array('url_name' => $data['url_name'], 'meta_title' => $data['meta_title']); + + $this->context->smarty->assign(array( + 'languages' => Language::getLanguages(false), + 'default_form_language' => (int)$this->context->controller->default_form_language, + 'values' => $values, + 'is_indexable' =>(bool)$is_indexable + )); + + return $this->display(__FILE__, 'attribute_group_form.tpl'); + } + + //ATTRIBUTES + public function hookAfterSaveAttribute($params) + { + if (!$params['id_attribute']) + return; + + Db::getInstance()->execute( + 'DELETE FROM '._DB_PREFIX_.'layered_indexable_attribute_lang_value + WHERE `id_attribute` = '.(int)$params['id_attribute'] + ); + + foreach (Language::getLanguages(false) as $language) + { + $seo_url = Tools::getValue('url_name_'.(int)$language['id_lang']); + + if(empty($seo_url)) + $seo_url = Tools::getValue('name_'.(int)$language['id_lang']); + + Db::getInstance()->execute( + 'INSERT INTO '._DB_PREFIX_.'layered_indexable_attribute_lang_value + VALUES ( + '.(int)$params['id_attribute'].', '.(int)$language['id_lang'].', + \''.pSQL(Tools::link_rewrite($seo_url)).'\', + \''.pSQL(Tools::getValue('meta_title_'.(int)$language['id_lang']), true).'\' + )' + ); + } + } + + public function hookAfterDeleteAttribute($params) + { + if (!$params['id_attribute']) + return; + + Db::getInstance()->execute( + 'DELETE FROM '._DB_PREFIX_.'layered_indexable_attribute_lang_value + WHERE `id_attribute` = '.(int)$params['id_attribute'] + ); + } + + public function hookPostProcessAttribute($params) + { + $errors = array(); + + foreach (Language::getLanguages(false) as $language) + { + $id_lang = $language['id_lang']; + + if (Tools::getValue('url_name_'.$id_lang)) + if (Tools::link_rewrite(Tools::getValue('url_name_'.$id_lang)) != strtolower(Tools::getValue('url_name_'.$id_lang))) + $params['errors'][] = Tools::displayError(sprintf($this->l('"%s" is not a valid url'), + Tools::getValue('url_name_'.$id_lang))); + } + } + + public function hookAttributeForm($params) + { + $values = array(); + + if ($result = Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS( + 'SELECT `url_name`, `meta_title`, `id_lang` + FROM '._DB_PREFIX_.'layered_indexable_attribute_lang_value + WHERE `id_attribute` = '.(int)$params['id_attribute'] + )) + foreach ($result as $data) + $values[$data['id_lang']] = array('url_name' => $data['url_name'], 'meta_title' => $data['meta_title']); + + $this->context->smarty->assign(array( + 'languages' => Language::getLanguages(false), + 'default_form_language' => (int)$this->context->controller->default_form_language, + 'values' => $values + )); + + return $this->display(__FILE__, 'attribute_form.tpl'); + } + + //FEATURES + public function hookAfterSaveFeature($params) + { + if (!$params['id_feature'] || Tools::getValue('layered_indexable') === false) + return; + + Db::getInstance()->execute( + 'DELETE FROM '._DB_PREFIX_.'layered_indexable_feature + WHERE `id_feature` = '.(int)$params['id_feature'] + ); + Db::getInstance()->execute( + 'DELETE FROM '._DB_PREFIX_.'layered_indexable_feature_lang_value + WHERE `id_feature` = '.(int)$params['id_feature'] + ); + + Db::getInstance()->execute( + 'INSERT INTO '._DB_PREFIX_.'layered_indexable_feature + VALUES ('.(int)$params['id_feature'].', '.(int)Tools::getValue('layered_indexable').')' + ); + + foreach (Language::getLanguages(false) as $language) + { + $seo_url = Tools::getValue('url_name_'.(int)$language['id_lang']); + + if(empty($seo_url)) + $seo_url = Tools::getValue('name_'.(int)$language['id_lang']); + + Db::getInstance()->execute( + 'INSERT INTO '._DB_PREFIX_.'layered_indexable_feature_lang_value + VALUES ( + '.(int)$params['id_feature'].', '.(int)$language['id_lang'].', + \''.pSQL(Tools::link_rewrite($seo_url)).'\', + \''.pSQL(Tools::getValue('meta_title_'.(int)$language['id_lang']), true).'\' + )' + ); + } + } + + public function hookAfterDeleteFeature($params) + { + if (!$params['id_feature']) + return; + + Db::getInstance()->execute( + 'DELETE FROM '._DB_PREFIX_.'layered_indexable_feature + WHERE `id_feature` = '.(int)$params['id_feature'] + ); + } + + public function hookPostProcessFeature($params) + { + $errors = array(); + + foreach (Language::getLanguages(false) as $language) + { + $id_lang = $language['id_lang']; + + if (Tools::getValue('url_name_'.$id_lang)) + if (Tools::link_rewrite(Tools::getValue('url_name_'.$id_lang)) != strtolower(Tools::getValue('url_name_'.$id_lang))) + $params['errors'][] = Tools::displayError(sprintf($this->l('"%s" is not a valid url'), + Tools::getValue('url_name_'.$id_lang))); + } + } + + public function hookFeatureForm($params) + { + $values = array(); + $is_indexable = Db::getInstance(_PS_USE_SQL_SLAVE_)->getValue( + 'SELECT `indexable` + FROM '._DB_PREFIX_.'layered_indexable_feature + WHERE `id_feature` = '.(int)$params['id_feature'] + ); + + if ($is_indexable === false) + $is_indexable = true; + + if ($result = Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS( + 'SELECT `url_name`, `meta_title`, `id_lang` FROM '._DB_PREFIX_.'layered_indexable_feature_lang_value + WHERE `id_feature` = '.(int)$params['id_feature'] + )) + foreach ($result as $data) + $values[$data['id_lang']] = array('url_name' => $data['url_name'], 'meta_title' => $data['meta_title']); + + $this->context->smarty->assign(array( + 'languages' => Language::getLanguages(false), + 'default_form_language' => (int)$this->context->controller->default_form_language, + 'values' => $values, + 'is_indexable' =>(bool)$is_indexable + )); + + return $this->display(__FILE__, 'feature_form.tpl'); + } + + //FEATURES VALUE + public function hookAfterSaveFeatureValue($params) + { + if (!$params['id_feature_value']) + return; + + //Removing all indexed language data for this attribute value id + Db::getInstance()->execute( + 'DELETE FROM '._DB_PREFIX_.'layered_indexable_feature_value_lang_value + WHERE `id_feature_value` = '.(int)$params['id_feature_value'] + ); + + foreach (Language::getLanguages(false) as $language) + { + $seo_url = Tools::getValue('url_name_'.(int)$language['id_lang']); + + if(empty($seo_url)) + $seo_url = Tools::getValue('name_'.(int)$language['id_lang']); + + Db::getInstance()->execute( + 'INSERT INTO '._DB_PREFIX_.'layered_indexable_feature_value_lang_value + VALUES ( + '.(int)$params['id_feature_value'].', '.(int)$language['id_lang'].', + \''.pSQL(Tools::link_rewrite($seo_url)).'\', + \''.pSQL(Tools::getValue('meta_title_'.(int)$language['id_lang']), true).'\' + )' + ); + } + } + + public function hookAfterDeleteFeatureValue($params) + { + if (!$params['id_feature_value']) + return; + + Db::getInstance()->execute( + 'DELETE FROM '._DB_PREFIX_.'layered_indexable_feature_value_lang_value + WHERE `id_feature_value` = '.(int)$params['id_feature_value'] + ); + } + + public function hookPostProcessFeatureValue($params) + { + $errors = array(); + + foreach (Language::getLanguages(false) as $language) + { + $id_lang = $language['id_lang']; + + if (Tools::getValue('url_name_'.$id_lang)) + if (Tools::link_rewrite(Tools::getValue('url_name_'.$id_lang)) != strtolower(Tools::getValue('url_name_'.$id_lang))) + $params['errors'][] = Tools::displayError(sprintf($this->l('"%s" is not a valid url'), + Tools::getValue('url_name_'.$id_lang))); + } + } + + public function hookFeatureValueForm($params) + { + $values = array(); + + if ($result = Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS( + 'SELECT `url_name`, `meta_title`, `id_lang` + FROM '._DB_PREFIX_.'layered_indexable_feature_value_lang_value + WHERE `id_feature_value` = '.(int)$params['id_feature_value'] + )) + foreach ($result as $data) + $values[$data['id_lang']] = array('url_name' => $data['url_name'], 'meta_title' => $data['meta_title']); + + $this->context->smarty->assign(array( + 'languages' => Language::getLanguages(false), + 'default_form_language' => (int)$this->context->controller->default_form_language, + 'values' => $values + )); + + return $this->display(__FILE__, 'feature_value_form.tpl'); + } + + public function hookProductListAssign($params) + { + global $smarty; + if (!Configuration::getGlobalValue('PS_LAYERED_INDEXED')) + return; + // Inform the hook was executed + $params['hookExecuted'] = true; + // List of product to overrride categoryController + $params['catProducts'] = array(); + $selected_filters = $this->getSelectedFilters(); + $filter_block = $this->getFilterBlock($selected_filters); + $title = ''; + if (is_array($filter_block['title_values'])) + foreach ($filter_block['title_values'] as $key => $val) + $title .= ' – '.$key.' '.implode('/', $val); + + $smarty->assign('categoryNameComplement', $title); + $this->getProducts($selected_filters, $params['catProducts'], $params['nbProducts'], $p, $n, $pages_nb, $start, $stop, $range); + // Need a nofollow on the pagination links? + $smarty->assign('no_follow', $filter_block['no_follow']); + } + + public function hookAfterSaveProduct($params) + { + if (!$params['id_product']) + return; + + self::indexProductPrices((int)$params['id_product']); + $this->indexAttribute((int)$params['id_product']); + } + + public function hookLeftColumn($params) + { + return $this->generateFiltersBlock($this->getSelectedFilters()); + } + + public function hookRightColumn($params) + { + return $this->hookLeftColumn($params); + } + + public function hookDisplayBackOfficeHeader() + { + + } + + public function hookHeader($params) + { + global $smarty, $cookie; + + // No filters => module disable + if ($filter_block = $this->getFilterBlock($this->getSelectedFilters())) + if ($filter_block['nbr_filterBlocks'] == 0) + return false; + + if (Tools::getValue('id_category', Tools::getValue('id_category_layered', 1)) == 1) + return; + + $id_lang = (int)$cookie->id_lang; + $category = new Category((int)Tools::getValue('id_category')); + + // Generate meta title and meta description + $category_title = (empty($category->meta_title[$id_lang]) ? $category->name[$id_lang] : $category->meta_title[$id_lang]); + $title = ''; + $description = ''; + $keywords = ''; + if (is_array($filter_block['meta_values'])) + foreach ($filter_block['meta_values'] as $key => $val) + { + if (!empty($val['title'])) + $val['title'] = $val['title'].' '; + + foreach ($val['values'] as $value) + { + $title .= $category_title.' '.$val['title'].$value.' - '; + $description .= $category_title.' '.$val['title'].$value.', '; + $keywords .= $val['title'].$value.', '; + } + } + // Title attributes (ex: / - ) + $title = strtolower(rtrim(substr($title, 0, -3))); + // Title attributes (ex: /, ) + $description = strtolower(rtrim(substr($description, 0, -2))); + // kewords attributes (ex: , , ) + $category_metas = Meta::getMetaTags($id_lang, 'category', $title); + + if (!empty($title)) + { + $smarty->assign('meta_title', ucfirst(substr($category_metas['meta_title'], 3))); + $smarty->assign('meta_description', $description.'. '.$category_metas['meta_description']); + } + else + $smarty->assign('meta_title', $category_metas['meta_title']); + + $keywords = substr(strtolower($keywords), 0, 1000); + if (!empty($keywords)) + $smarty->assign('meta_keywords', rtrim($category_title.', '.$keywords.', '.$category_metas['meta_keywords'], ', ')); + + + $this->context->controller->addJS(($this->_path).'blocklayered.js'); + $this->context->controller->addJS(_PS_JS_DIR_.'jquery/jquery-ui-1.8.10.custom.min.js'); + $this->context->controller->addJQueryUI('ui.slider'); + $this->context->controller->addCSS(_PS_CSS_DIR_.'jquery-ui-1.8.10.custom.css"'); + $this->context->controller->addCSS(($this->_path).'blocklayered-15.css', 'all'); + $this->context->controller->addJQueryPlugin('scrollTo'); + + $filters = $this->getSelectedFilters(); + + // Get non indexable attributes + $attribute_group_list = Db::getInstance()->executeS('SELECT id_attribute_group FROM '._DB_PREFIX_.'layered_indexable_attribute_group WHERE indexable = 0'); + // Get non indexable features + $feature_list = Db::getInstance()->executeS('SELECT id_feature FROM '._DB_PREFIX_.'layered_indexable_feature WHERE indexable = 0'); + + $attributes = array(); + $features = array(); + + $blacklist = array('weight', 'price'); + if (!Configuration::get('PS_LAYERED_FILTER_INDEX_CDT')) + $blacklist[] = 'condition'; + if (!Configuration::get('PS_LAYERED_FILTER_INDEX_QTY')) + $blacklist[] = 'quantity'; + if (!Configuration::get('PS_LAYERED_FILTER_INDEX_MNF')) + $blacklist[] = 'manufacturer'; + if (!Configuration::get('PS_LAYERED_FILTER_INDEX_CAT')) + $blacklist[] = 'category'; + + foreach ($filters as $type => $val) + { + switch ($type) + { + case 'id_attribute_group': + foreach ($val as $attr) + { + $attr_id = preg_replace('/_\d+$/', '', $attr); + if (in_array($attr_id, $attributes) || in_array(array('id_attribute_group' => $attr_id), $attribute_group_list)) + { + $smarty->assign('nobots', true); + $smarty->assign('nofollow', true); + return; + } + $attributes[] = $attr_id; + } + break; + case 'id_feature': + foreach ($val as $feat) + { + $feat_id = preg_replace('/_\d+$/', '', $feat); + if (in_array($feat_id, $features) || in_array(array('id_feature' => $feat_id), $feature_list)) + { + $smarty->assign('nobots', true); + $smarty->assign('nofollow', true); + return; + } + $features[] = $feat_id; + } + break; + default: + if (in_array($type, $blacklist)) + { + if (count($val)) + { + $smarty->assign('nobots', true); + $smarty->assign('nofollow', true); + return; + } + } + elseif (count($val) > 1) + { + $smarty->assign('nobots', true); + $smarty->assign('nofollow', true); + return; + } + break; + } + } + } + + public function hookFooter($params) + { + // No filters => module disable + if ($filter_block = $this->getFilterBlock($this->getSelectedFilters())) + if ($filter_block['nbr_filterBlocks'] == 0) + return false; + + if (Dispatcher::getInstance()->getController() == 'category') + return ' + '; + } + + public function hookCategoryAddition($params) + { + $this->rebuildLayeredCache(array(), array((int)$params['category']->id)); + } + + public function hookCategoryUpdate($params) + { + /* The category status might (active, inactive) have changed, we have to update the layered cache table structure */ + if (isset($params['category']) && !$params['category']->active) + $this->hookCategoryDeletion($params); + } + + public function hookCategoryDeletion($params) + { + $layered_filter_list = Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS( + 'SELECT * FROM '._DB_PREFIX_.'layered_filter' + ); + + foreach ($layered_filter_list as $layered_filter) + { + $data = Tools::unSerialize($layered_filter['filters']); + + if (in_array((int)$params['category']->id, $data['categories'])) + { + unset($data['categories'][array_search((int)$params['category']->id, $data['categories'])]); + Db::getInstance()->execute( + 'UPDATE `'._DB_PREFIX_.'layered_filter` + SET `filters` = \''.pSQL(serialize($data)).'\' + WHERE `id_layered_filter` = '.(int)$layered_filter['id_layered_filter'] + ); + } + } + + $this->buildLayeredCategories(); + } + + /* * Generate data product attribute */ public function indexAttribute($id_product = null) @@ -259,20 +837,26 @@ class BlockLayered extends Module if (is_null($id_product)) Db::getInstance()->execute('TRUNCATE '._DB_PREFIX_.'layered_product_attribute'); else - Db::getInstance()->execute('DELETE FROM '._DB_PREFIX_.'layered_product_attribute WHERE id_product = '.(int)$id_product); + Db::getInstance()->execute(' + DELETE FROM '._DB_PREFIX_.'layered_product_attribute + WHERE id_product = '.(int)$id_product + ); - Db::getInstance()->execute('INSERT INTO `'._DB_PREFIX_.'layered_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 - '.(is_null($id_product) ? '' : 'AND pa.id_product = '.(int)$id_product).' - GROUP BY a.id_attribute, pa.id_product , product_attribute_shop.`id_shop`'); + Db::getInstance()->execute(' + INSERT INTO `'._DB_PREFIX_.'layered_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 + '.(is_null($id_product) ? '' : 'AND pa.id_product = '.(int)$id_product).' + GROUP BY a.id_attribute, pa.id_product , product_attribute_shop.`id_shop`' + ); return 1; } + /* * Url indexation */ @@ -282,10 +866,13 @@ class BlockLayered extends Module Db::getInstance()->execute('TRUNCATE '._DB_PREFIX_.'layered_friendly_url'); $attribute_values_by_lang = array(); - $filters = Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS('SELECT lc.*, id_lang, name, link_rewrite, cl.id_category - FROM '._DB_PREFIX_.'layered_category lc - INNER JOIN '._DB_PREFIX_.'category_lang cl ON (cl.id_category = lc.id_category AND lc.id_category <> 1 ) - GROUP BY type, id_value, id_lang'); + $filters = Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS(' + SELECT lc.*, id_lang, name, link_rewrite, cl.id_category + FROM '._DB_PREFIX_.'layered_category lc + INNER JOIN '._DB_PREFIX_.'category_lang cl ON (cl.id_category = lc.id_category AND lc.id_category <> 1 ) + GROUP BY type, id_value, id_lang' + ); + if (!$filters) return; @@ -294,18 +881,20 @@ class BlockLayered extends Module { case 'id_attribute_group': $attributes = Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS(' - SELECT agl.public_name name, a.id_attribute_group id_name, al.name value, a.id_attribute id_value, al.id_lang, - liagl.url_name name_url_name, lial.url_name value_url_name - FROM '._DB_PREFIX_.'attribute_group ag - INNER JOIN '._DB_PREFIX_.'attribute_group_lang agl ON (agl.id_attribute_group = ag.id_attribute_group) - INNER JOIN '._DB_PREFIX_.'attribute a ON (a.id_attribute_group = ag.id_attribute_group) - INNER JOIN '._DB_PREFIX_.'attribute_lang al ON (al.id_attribute = a.id_attribute) - LEFT JOIN '._DB_PREFIX_.'layered_indexable_attribute_group liag ON (liag.id_attribute_group = a.id_attribute_group) - LEFT JOIN '._DB_PREFIX_.'layered_indexable_attribute_group_lang_value liagl - ON (liagl.id_attribute_group = ag.id_attribute_group AND liagl.id_lang = '.(int)$filter['id_lang'].') - LEFT JOIN '._DB_PREFIX_.'layered_indexable_attribute_lang_value lial - ON (lial.id_attribute = a.id_attribute AND lial.id_lang = '.(int)$filter['id_lang'].') - WHERE a.id_attribute_group = '.(int)$filter['id_value'].' AND agl.id_lang = al.id_lang AND agl.id_lang = '.(int)$filter['id_lang']); + SELECT agl.public_name name, a.id_attribute_group id_name, al.name value, a.id_attribute id_value, al.id_lang, + liagl.url_name name_url_name, lial.url_name value_url_name + FROM '._DB_PREFIX_.'attribute_group ag + INNER JOIN '._DB_PREFIX_.'attribute_group_lang agl ON (agl.id_attribute_group = ag.id_attribute_group) + INNER JOIN '._DB_PREFIX_.'attribute a ON (a.id_attribute_group = ag.id_attribute_group) + INNER JOIN '._DB_PREFIX_.'attribute_lang al ON (al.id_attribute = a.id_attribute) + LEFT JOIN '._DB_PREFIX_.'layered_indexable_attribute_group liag ON (liag.id_attribute_group = a.id_attribute_group) + LEFT JOIN '._DB_PREFIX_.'layered_indexable_attribute_group_lang_value liagl + ON (liagl.id_attribute_group = ag.id_attribute_group AND liagl.id_lang = '.(int)$filter['id_lang'].') + LEFT JOIN '._DB_PREFIX_.'layered_indexable_attribute_lang_value lial + ON (lial.id_attribute = a.id_attribute AND lial.id_lang = '.(int)$filter['id_lang'].') + WHERE a.id_attribute_group = '.(int)$filter['id_value'].' AND agl.id_lang = al.id_lang AND agl.id_lang = '.(int)$filter['id_lang'] + ); + foreach ($attributes as $attribute) { if (!isset($attribute_values_by_lang[$attribute['id_lang']])) @@ -325,17 +914,19 @@ class BlockLayered extends Module case 'id_feature': $features = Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS(' - SELECT fl.name name, fl.id_feature id_name, fvl.id_feature_value id_value, fvl.value value, fl.id_lang, fl.id_lang, - lifl.url_name name_url_name, lifvl.url_name value_url_name - FROM '._DB_PREFIX_.'feature_lang fl - LEFT JOIN '._DB_PREFIX_.'layered_indexable_feature lif ON (lif.id_feature = fl.id_feature) - INNER JOIN '._DB_PREFIX_.'feature_value fv ON (fv.id_feature = fl.id_feature) - INNER JOIN '._DB_PREFIX_.'feature_value_lang fvl ON (fvl.id_feature_value = fv.id_feature_value) - LEFT JOIN '._DB_PREFIX_.'layered_indexable_feature_lang_value lifl - ON (lifl.id_feature = fl.id_feature AND lifl.id_lang = '.(int)$filter['id_lang'].') - LEFT JOIN '._DB_PREFIX_.'layered_indexable_feature_value_lang_value lifvl - ON (lifvl.id_feature_value = fvl.id_feature_value AND lifvl.id_lang = '.(int)$filter['id_lang'].') - WHERE fl.id_feature = '.(int)$filter['id_value'].' AND fvl.id_lang = fl.id_lang AND fvl.id_lang = '.(int)$filter['id_lang']); + SELECT fl.name name, fl.id_feature id_name, fvl.id_feature_value id_value, fvl.value value, fl.id_lang, fl.id_lang, + lifl.url_name name_url_name, lifvl.url_name value_url_name + FROM '._DB_PREFIX_.'feature_lang fl + LEFT JOIN '._DB_PREFIX_.'layered_indexable_feature lif ON (lif.id_feature = fl.id_feature) + INNER JOIN '._DB_PREFIX_.'feature_value fv ON (fv.id_feature = fl.id_feature) + INNER JOIN '._DB_PREFIX_.'feature_value_lang fvl ON (fvl.id_feature_value = fv.id_feature_value) + LEFT JOIN '._DB_PREFIX_.'layered_indexable_feature_lang_value lifl + ON (lifl.id_feature = fl.id_feature AND lifl.id_lang = '.(int)$filter['id_lang'].') + LEFT JOIN '._DB_PREFIX_.'layered_indexable_feature_value_lang_value lifvl + ON (lifvl.id_feature_value = fvl.id_feature_value AND lifvl.id_lang = '.(int)$filter['id_lang'].') + WHERE fl.id_feature = '.(int)$filter['id_value'].' AND fvl.id_lang = fl.id_lang AND fvl.id_lang = '.(int)$filter['id_lang'] + ); + foreach ($features as $feature) { if (!isset($attribute_values_by_lang[$feature['id_lang']])) @@ -355,10 +946,12 @@ class BlockLayered extends Module case 'category': $categories = Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS(' - SELECT cl.name, cl.id_lang, c.id_category - FROM '._DB_PREFIX_.'category c - INNER JOIN '._DB_PREFIX_.'category_lang cl ON (c.id_category = cl.id_category) - WHERE cl.id_lang = '.(int)$filter['id_lang']); + SELECT cl.name, cl.id_lang, c.id_category + FROM '._DB_PREFIX_.'category c + INNER JOIN '._DB_PREFIX_.'category_lang cl ON (c.id_category = cl.id_category) + WHERE cl.id_lang = '.(int)$filter['id_lang'] + ); + foreach ($categories as $category) { if (!isset($attribute_values_by_lang[$category['id_lang']])) @@ -373,9 +966,10 @@ class BlockLayered extends Module case 'manufacturer': $manufacturers = Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS(' - SELECT m.name as name,l.id_lang as id_lang, id_manufacturer - FROM '._DB_PREFIX_.'manufacturer m , '._DB_PREFIX_.'lang l - WHERE l.id_lang = '.(int)$filter['id_lang'].' '); + SELECT m.name as name,l.id_lang as id_lang, id_manufacturer + FROM '._DB_PREFIX_.'manufacturer m , '._DB_PREFIX_.'lang l + WHERE l.id_lang = '.(int)$filter['id_lang'] + ); foreach ($manufacturers as $manufacturer) { @@ -418,632 +1012,35 @@ class BlockLayered extends Module { // Foreach attributes generate a couple "/_". For example: color_blue foreach ($attribute_values as $attribute) - foreach ($attribute as $param) + foreach ($attribute as $param) + { + $selected_filters = array(); + $link = '/'.str_replace(Configuration::get('PS_ATTRIBUTE_ANCHOR_SEPARATOR'), '_', Tools::link_rewrite($param['name'])).Configuration::get('PS_ATTRIBUTE_ANCHOR_SEPARATOR').str_replace(Configuration::get('PS_ATTRIBUTE_ANCHOR_SEPARATOR'), '_', Tools::link_rewrite($param['value'])); + $selected_filters[$param['type']] = array(); + + if (!isset($param['id_id_value'])) + $param['id_id_value'] = $param['id_value']; + + $selected_filters[$param['type']][$param['id_id_value']] = $param['id_value']; + $url_key = md5($link); + $id_layered_friendly_url = Db::getInstance()->getValue(' + SELECT id_layered_friendly_url + FROM `'._DB_PREFIX_.'layered_friendly_url` WHERE `id_lang` = '.$id_lang.' AND `url_key` = \''.$url_key.'\'' + ); + + if ($id_layered_friendly_url == false) { - $selected_filters = array(); - $link = '/'.str_replace(Configuration::get('PS_ATTRIBUTE_ANCHOR_SEPARATOR'), '_', Tools::link_rewrite($param['name'])).Configuration::get('PS_ATTRIBUTE_ANCHOR_SEPARATOR').str_replace(Configuration::get('PS_ATTRIBUTE_ANCHOR_SEPARATOR'), '_', Tools::link_rewrite($param['value'])); - $selected_filters[$param['type']] = array(); - if (!isset($param['id_id_value'])) - $param['id_id_value'] = $param['id_value']; - $selected_filters[$param['type']][$param['id_id_value']] = $param['id_value']; - $url_key = md5($link); - $id_layered_friendly_url = Db::getInstance()->getValue('SELECT id_layered_friendly_url - FROM `'._DB_PREFIX_.'layered_friendly_url` WHERE `id_lang` = '.$id_lang.' AND `url_key` = \''.$url_key.'\''); - if ($id_layered_friendly_url == false) - { - Db::getInstance()->AutoExecute(_DB_PREFIX_.'layered_friendly_url', array('url_key' => $url_key, 'data' => serialize($selected_filters), 'id_lang' => $id_lang), 'INSERT'); - $id_layered_friendly_url = Db::getInstance()->Insert_ID(); - } + Db::getInstance()->AutoExecute(_DB_PREFIX_.'layered_friendly_url', array('url_key' => $url_key, 'data' => serialize($selected_filters), 'id_lang' => $id_lang), 'INSERT'); + $id_layered_friendly_url = Db::getInstance()->Insert_ID(); } + } } + if ($ajax) return '{"result": 1}'; else return 1; - } - - public function translateWord($string, $id_lang ) - { - static $_MODULES = array(); - global $_MODULE; - - $file = _PS_MODULE_DIR_.$this->name.'/translations/'.Language::getIsoById($id_lang).'.php'; - - if (!array_key_exists($id_lang, $_MODULES)) - { - if (file_exists($file1 = _PS_MODULE_DIR_.$this->name.'/translations/'.Language::getIsoById($id_lang).'.php')) - { - include($file1); - $_MODULES[$id_lang] = $_MODULE; - } - elseif (file_exists($file2 = _PS_MODULE_DIR_.$this->name.'/'.Language::getIsoById($id_lang).'.php')) - { - include($file2); - $_MODULES[$id_lang] = $_MODULE; - } - else - return $string; - } - - $string = str_replace('\'', '\\\'', $string); - - // set array key to lowercase for 1.3 compatibility - $_MODULES[$id_lang] = array_change_key_case($_MODULES[$id_lang]); - $current_key = '<{'.strtolower( $this->name).'}'.strtolower(_THEME_NAME_).'>'.strtolower($this->name).'_'.md5($string); - $default_key = '<{'.strtolower( $this->name).'}prestashop>'.strtolower($this->name).'_'.md5($string); - - if (isset($_MODULES[$id_lang][$current_key])) - $ret = stripslashes($_MODULES[$id_lang][$current_key]); - else if (isset($_MODULES[$id_lang][Tools::strtolower($current_key)])) - $ret = stripslashes($_MODULES[$id_lang][Tools::strtolower($current_key)]); - else if (isset($_MODULES[$id_lang][$default_key])) - $ret = stripslashes($_MODULES[$id_lang][$default_key]); - else if (isset($_MODULES[$id_lang][Tools::strtolower($default_key)])) - $ret = stripslashes($_MODULES[$id_lang][Tools::strtolower($default_key)]); - else - $ret = stripslashes($string); - - return str_replace('"', '"', $ret); - } - - public function hookProductListAssign($params) - { - global $smarty; - if (!Configuration::getGlobalValue('PS_LAYERED_INDEXED')) - return; - // Inform the hook was executed - $params['hookExecuted'] = true; - // List of product to overrride categoryController - $params['catProducts'] = array(); - $selected_filters = $this->getSelectedFilters(); - $filter_block = $this->getFilterBlock($selected_filters); - $title = ''; - if (is_array($filter_block['title_values'])) - foreach ($filter_block['title_values'] as $key => $val) - $title .= ' – '.$key.' '.implode('/', $val); - - $smarty->assign('categoryNameComplement', $title); - $this->getProducts($selected_filters, $params['catProducts'], $params['nbProducts'], $p, $n, $pages_nb, $start, $stop, $range); - // Need a nofollow on the pagination links? - $smarty->assign('no_follow', $filter_block['no_follow']); - } - - public function hookAfterSaveProduct($params) - { - if (!$params['id_product']) - return; - - self::indexProductPrices((int)$params['id_product']); - $this->indexAttribute((int)$params['id_product']); - } - - public function hookAfterSaveFeature($params) - { - if (!$params['id_feature'] || Tools::getValue('layered_indexable') === false) - return; - - Db::getInstance()->execute('DELETE FROM '._DB_PREFIX_.'layered_indexable_feature WHERE id_feature = '.(int)$params['id_feature']); - Db::getInstance()->execute('INSERT INTO '._DB_PREFIX_.'layered_indexable_feature VALUES ('.(int)$params['id_feature'].', '.(int)Tools::getValue('layered_indexable').')'); - - Db::getInstance()->execute('DELETE FROM '._DB_PREFIX_.'layered_indexable_feature_lang_value WHERE id_feature = '.(int)$params['id_feature']); // don't care about the id_lang - foreach (Language::getLanguages(false) as $language) - { - // Data are validated by method "hookPostProcessFeature" - $id_lang = (int)$language['id_lang']; - Db::getInstance()->execute('INSERT INTO '._DB_PREFIX_.'layered_indexable_feature_lang_value - VALUES ('.(int)$params['id_feature'].', '.$id_lang.', \''.pSQL(Tools::link_rewrite(Tools::getValue('url_name_'.$id_lang))).'\', - \''.pSQL(Tools::getValue('meta_title_'.$id_lang), true).'\')'); - } - } - - public function hookAfterSaveFeatureValue($params) - { - if (!$params['id_feature_value']) - return; - - Db::getInstance()->execute('DELETE FROM '._DB_PREFIX_.'layered_indexable_feature_value_lang_value WHERE id_feature_value = '.(int)$params['id_feature_value']); // don't care about the id_lang - foreach (Language::getLanguages(false) as $language) - { - // Data are validated by method "hookPostProcessFeatureValue" - $id_lang = (int)$language['id_lang']; - Db::getInstance()->execute('INSERT INTO '._DB_PREFIX_.'layered_indexable_feature_value_lang_value - VALUES ('.(int)$params['id_feature_value'].', '.$id_lang.', \''.pSQL(Tools::link_rewrite(Tools::getValue('url_name_'.$id_lang))).'\', - \''.pSQL(Tools::getValue('meta_title_'.$id_lang), true).'\')'); - } - } - - public function hookAfterDeleteFeatureValue($params) - { - if (!$params['id_feature_value']) - return; - Db::getInstance()->execute('DELETE FROM '._DB_PREFIX_.'layered_indexable_feature_value_lang_value WHERE id_feature_value = '.(int)$params['id_feature_value']); - } - - public function hookPostProcessFeatureValue($params) - { - $this->hookPostProcessAttributeGroup($params); - } - - public function hookFeatureValueForm($params) - { - $languages = Language::getLanguages(false); - $default_form_language = (int)$this->context->controller->default_form_language; - $lang_value = array(); - - $result = Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS( - 'SELECT url_name, meta_title, id_lang FROM '._DB_PREFIX_.'layered_indexable_feature_value_lang_value - WHERE id_feature_value = '.(int)$params['id_feature_value']); - if ($result) - foreach ($result as $data) - $lang_value[$data['id_lang']] = array('url_name' => $data['url_name'], 'meta_title' => $data['meta_title']); - - $return = '
- -
-
'; - foreach ($languages as $language) - { - $return .= ' -
-
- -
-
- - -
-
'; - } - - $return .= '
-

'.$this->l('Specific URL format in block layered generation').'

-
-
-
-
-
- -
-
'; - foreach ($languages as $language) - { - $return .= ' -
-
- -
-
- - -
-
'; - } - - $return .= '
-

'.$this->l('Specific format for meta title').'

-
-
- -
-
'; - return $return; - } - - public function hookAfterSaveAttribute($params) - { - if (!$params['id_attribute']) - return; - - Db::getInstance()->execute('DELETE FROM '._DB_PREFIX_.'layered_indexable_attribute_lang_value WHERE id_attribute = '.(int)$params['id_attribute']); // don't care about the id_lang - foreach (Language::getLanguages(false) as $language) - { - // Data are validated by method "hookPostProcessAttribute" - $id_lang = (int)$language['id_lang']; - Db::getInstance()->execute('INSERT INTO '._DB_PREFIX_.'layered_indexable_attribute_lang_value - VALUES ('.(int)$params['id_attribute'].', '.$id_lang.', \''.pSQL(Tools::link_rewrite(Tools::getValue('url_name_'.$id_lang))).'\', - \''.pSQL(Tools::getValue('meta_title_'.$id_lang), true).'\')'); - } - } - - public function hookAfterDeleteAttribute($params) - { - if (!$params['id_attribute']) - return; - Db::getInstance()->execute('DELETE FROM '._DB_PREFIX_.'layered_indexable_attribute_lang_value WHERE id_attribute = '.(int)$params['id_attribute']); - } - - public function hookPostProcessAttribute($params) - { - $this->hookPostProcessAttributeGroup($params); - } - - public function hookAttributeForm($params) - { - $languages = Language::getLanguages(false); - $default_form_language = (int)$this->context->controller->default_form_language; - $lang_value = array(); - - $result = Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS( - 'SELECT url_name, meta_title, id_lang FROM '._DB_PREFIX_.'layered_indexable_attribute_lang_value - WHERE id_attribute = '.(int)$params['id_attribute']); - if ($result) - foreach ($result as $data) - $lang_value[$data['id_lang']] = array('url_name' => $data['url_name'], 'meta_title' => $data['meta_title']); - - $return = '
- -
-
'; - foreach ($languages as $language) - { - $return .= ' -
-
- -
-
- - -
-
'; - } - - $return .= '
-

'.$this->l('Specific URL format in block layered generation').'

-
-
-
-
-
- -
-
'; - foreach ($languages as $language) - { - $return .= ' -
-
- -
-
- - -
-
'; - } - - $return .= '
-

'.$this->l('Specific format for meta title').'

-
-
- -
-
'; - return $return; - } - - public function hookPostProcessFeature($params) - { - $this->hookPostProcessAttributeGroup($params); - } - - public function hookAfterDeleteFeature($params) - { - if (!$params['id_feature']) - return; - Db::getInstance()->execute('DELETE FROM '._DB_PREFIX_.'layered_indexable_feature WHERE id_feature = '.(int)$params['id_feature']); - } - - public function hookAfterSaveAttributeGroup($params) - { - if (!$params['id_attribute_group'] || Tools::getValue('layered_indexable') === false) - return; - - Db::getInstance()->execute('DELETE FROM '._DB_PREFIX_.'layered_indexable_attribute_group WHERE id_attribute_group = '.(int)$params['id_attribute_group']); - Db::getInstance()->execute('INSERT INTO '._DB_PREFIX_.'layered_indexable_attribute_group VALUES ('.(int)$params['id_attribute_group'].', '.(int)Tools::getValue('layered_indexable').')'); - - Db::getInstance()->execute('DELETE FROM '._DB_PREFIX_.'layered_indexable_attribute_group_lang_value WHERE id_attribute_group = '.(int)$params['id_attribute_group']); // don't care about the id_lang - foreach (Language::getLanguages(false) as $language) - { - // Data are validated by method "hookPostProcessAttributeGroup" - $id_lang = (int)$language['id_lang']; - Db::getInstance()->execute('INSERT INTO '._DB_PREFIX_.'layered_indexable_attribute_group_lang_value - VALUES ('.(int)$params['id_attribute_group'].', '.$id_lang.', \''.pSQL(Tools::link_rewrite(Tools::getValue('url_name_'.$id_lang))).'\', - \''.pSQL(Tools::getValue('meta_title_'.$id_lang), true).'\')'); - } - } - - public function hookPostProcessAttributeGroup($params) - { - // Limit to one call - static $once = false; - if ($once) - return; - $once = true; - - $errors = array(); - foreach (Language::getLanguages(false) as $language) - { - $id_lang = $language['id_lang']; - if (Tools::getValue('url_name_'.$id_lang)) - if (Tools::link_rewrite(Tools::getValue('url_name_'.$id_lang)) != strtolower( Tools::getValue('url_name_'.$id_lang))) - { - // Here use the reference "errors" to stop saving process - $params['errors'][] = Tools::displayError(sprintf($this->l('"%s" is not a valid url'), Tools::getValue('url_name_'.$id_lang))); - } - } - } - - public function hookAfterDeleteAttributeGroup($params) - { - if (!$params['id_attribute_group']) - return; - - Db::getInstance()->execute('DELETE FROM '._DB_PREFIX_.'layered_indexable_attribute_group WHERE id_attribute_group = '.(int)$params['id_attribute_group']); - Db::getInstance()->execute('DELETE FROM '._DB_PREFIX_.'layered_indexable_attribute_group_lang_value WHERE id_attribute_group = '.(int)$params['id_attribute_group']); - } - - public function hookAttributeGroupForm($params) - { - $languages = Language::getLanguages(false); - $default_form_language = (int)$this->context->controller->default_form_language; - $indexable = Db::getInstance(_PS_USE_SQL_SLAVE_)->getValue('SELECT indexable FROM '._DB_PREFIX_.'layered_indexable_attribute_group - WHERE id_attribute_group = '.(int)$params['id_attribute_group']); - $lang_value = array(); - - $result = Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS( - 'SELECT url_name, meta_title, id_lang FROM '._DB_PREFIX_.'layered_indexable_attribute_group_lang_value - WHERE id_attribute_group = '.(int)$params['id_attribute_group']); - if ($result) - foreach ($result as $data) - $lang_value[$data['id_lang']] = array('url_name' => $data['url_name'], 'meta_title' => $data['meta_title']); - - if ($indexable === false) - $on = true; - else - $on = (bool)$indexable; - - $return = '
- -
-
'; - foreach ($languages as $language) - { - $return .= ' -
-
- -
-
- - -
-
'; - } - - $return .= '
-

'.$this->l('Specific URL format in block layered generation').'

-
-
-
-
-
- -
-
'; - foreach ($languages as $language) - { - $return .= ' -
-
- -
-
- - -
-
'; - } - - $return .= '
-

'.$this->l('Specific format for meta title').'

-
-
- -
-
-
- -
-
-
- - - - - - - -
-
-
-
-

'.$this->l('Use this attribute in URL generated by the layered navigation module').'

-
-
'; - return $return; - } - - public function hookFeatureForm($params) - { - $languages = Language::getLanguages(false); - $default_form_language = (int)$this->context->controller->default_form_language; - $indexable = Db::getInstance(_PS_USE_SQL_SLAVE_)->getValue('SELECT indexable FROM '._DB_PREFIX_.'layered_indexable_feature WHERE id_feature = '.(int)$params['id_feature']); - $lang_value = array(); - - $result = Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS( - 'SELECT url_name, meta_title, id_lang FROM '._DB_PREFIX_.'layered_indexable_feature_lang_value - WHERE id_feature = '.(int)$params['id_feature']); - if ($result) - foreach ($result as $data) - $lang_value[$data['id_lang']] = array('url_name' => $data['url_name'], 'meta_title' => $data['meta_title']); - - - if ($indexable === false) - $on = true; - else - $on = (bool)$indexable; - - $return = '
- -
-
'; - foreach ($languages as $language) - { - $return .= ' -
-
- -
-
- - -
-
'; - } - - $return .= '
-

'.$this->l('Specific URL format in block layered generation').'

-
-
-
-
-
- -
-
'; - foreach ($languages as $language) - { - $return .= ' -
-
- -
-
- - -
-
'; - } - - $return .= '
-

'.$this->l('Specific format for meta title').'

-
-
- -
-
-
- -
-
-
- - - - - - - -
-
-
-
-

'.$this->l('Use this attribute in URL generated by the layered navigation module').'

-
-
'; - return $return; - } + } /* * $cursor $cursor in order to restart indexing from the last state @@ -1272,238 +1269,91 @@ class BlockLayered extends Module } } - public function hookLeftColumn($params) + public function translateWord($string, $id_lang ) { - return $this->generateFiltersBlock($this->getSelectedFilters()); - } + static $_MODULES = array(); + global $_MODULE; - public function hookRightColumn($params) - { - return $this->hookLeftColumn($params); - } + $file = _PS_MODULE_DIR_.$this->name.'/translations/'.Language::getIsoById($id_lang).'.php'; - public function hookDisplayBackOfficeHeader() - { - if (method_exists($this->context->controller, 'addJquery')) + if (!array_key_exists($id_lang, $_MODULES)) { - if (version_compare(_PS_VERSION_, '1.6.0', '>=') === TRUE) - $this->context->controller->addCSS($this->_path.'views/css/blocklayered_bt.css'); + if (file_exists($file1 = _PS_MODULE_DIR_.$this->name.'/translations/'.Language::getIsoById($id_lang).'.php')) + { + include($file1); + $_MODULES[$id_lang] = $_MODULE; + } + elseif (file_exists($file2 = _PS_MODULE_DIR_.$this->name.'/'.Language::getIsoById($id_lang).'.php')) + { + include($file2); + $_MODULES[$id_lang] = $_MODULE; + } else - $this->context->controller->addCSS($this->_path.'views/css/blocklayered.css'); + return $string; } - } - public function hookHeader($params) - { - global $smarty, $cookie; - - // No filters => module disable - if ($filter_block = $this->getFilterBlock($this->getSelectedFilters())) - if ($filter_block['nbr_filterBlocks'] == 0) - return false; - - if (Tools::getValue('id_category', Tools::getValue('id_category_layered', 1)) == 1) - return; - - $id_lang = (int)$cookie->id_lang; - $category = new Category((int)Tools::getValue('id_category')); + $string = str_replace('\'', '\\\'', $string); - // Generate meta title and meta description - $category_title = (empty($category->meta_title[$id_lang]) ? $category->name[$id_lang] : $category->meta_title[$id_lang]); - $title = ''; - $description = ''; - $keywords = ''; - if (is_array($filter_block['meta_values'])) - foreach ($filter_block['meta_values'] as $key => $val) - { - if (!empty($val['title'])) - $val['title'] = $val['title'].' '; - - foreach ($val['values'] as $value) - { - $title .= $category_title.' '.$val['title'].$value.' - '; - $description .= $category_title.' '.$val['title'].$value.', '; - $keywords .= $val['title'].$value.', '; - } - } - // Title attributes (ex: / - ) - $title = strtolower(rtrim(substr($title, 0, -3))); - // Title attributes (ex: /, ) - $description = strtolower(rtrim(substr($description, 0, -2))); - // kewords attributes (ex: , , ) - $category_metas = Meta::getMetaTags($id_lang, 'category', $title); - - if (!empty($title)) - { - $smarty->assign('meta_title', ucfirst(substr($category_metas['meta_title'], 3))); - $smarty->assign('meta_description', $description.'. '.$category_metas['meta_description']); - } + // set array key to lowercase for 1.3 compatibility + $_MODULES[$id_lang] = array_change_key_case($_MODULES[$id_lang]); + $current_key = '<{'.strtolower( $this->name).'}'.strtolower(_THEME_NAME_).'>'.strtolower($this->name).'_'.md5($string); + $default_key = '<{'.strtolower( $this->name).'}prestashop>'.strtolower($this->name).'_'.md5($string); + + if (isset($_MODULES[$id_lang][$current_key])) + $ret = stripslashes($_MODULES[$id_lang][$current_key]); + else if (isset($_MODULES[$id_lang][Tools::strtolower($current_key)])) + $ret = stripslashes($_MODULES[$id_lang][Tools::strtolower($current_key)]); + else if (isset($_MODULES[$id_lang][$default_key])) + $ret = stripslashes($_MODULES[$id_lang][$default_key]); + else if (isset($_MODULES[$id_lang][Tools::strtolower($default_key)])) + $ret = stripslashes($_MODULES[$id_lang][Tools::strtolower($default_key)]); else - $smarty->assign('meta_title', $category_metas['meta_title']); + $ret = stripslashes($string); - $keywords = substr(strtolower($keywords), 0, 1000); - if (!empty($keywords)) - $smarty->assign('meta_keywords', rtrim($category_title.', '.$keywords.', '.$category_metas['meta_keywords'], ', ')); - - - $this->context->controller->addJS(($this->_path).'blocklayered.js'); - $this->context->controller->addJS(_PS_JS_DIR_.'jquery/jquery-ui-1.8.10.custom.min.js'); - $this->context->controller->addJQueryUI('ui.slider'); - $this->context->controller->addCSS(_PS_CSS_DIR_.'jquery-ui-1.8.10.custom.css"'); - $this->context->controller->addCSS(($this->_path).'blocklayered-15.css', 'all'); - $this->context->controller->addJQueryPlugin('scrollTo'); - - $filters = $this->getSelectedFilters(); - - // Get non indexable attributes - $attribute_group_list = Db::getInstance()->executeS('SELECT id_attribute_group FROM '._DB_PREFIX_.'layered_indexable_attribute_group WHERE indexable = 0'); - // Get non indexable features - $feature_list = Db::getInstance()->executeS('SELECT id_feature FROM '._DB_PREFIX_.'layered_indexable_feature WHERE indexable = 0'); - - $attributes = array(); - $features = array(); - - $blacklist = array('weight', 'price'); - if (!Configuration::get('PS_LAYERED_FILTER_INDEX_CDT')) - $blacklist[] = 'condition'; - if (!Configuration::get('PS_LAYERED_FILTER_INDEX_QTY')) - $blacklist[] = 'quantity'; - if (!Configuration::get('PS_LAYERED_FILTER_INDEX_MNF')) - $blacklist[] = 'manufacturer'; - if (!Configuration::get('PS_LAYERED_FILTER_INDEX_CAT')) - $blacklist[] = 'category'; - - foreach ($filters as $type => $val) - { - switch ($type) - { - case 'id_attribute_group': - foreach ($val as $attr) - { - $attr_id = preg_replace('/_\d+$/', '', $attr); - if (in_array($attr_id, $attributes) || in_array(array('id_attribute_group' => $attr_id), $attribute_group_list)) - { - $smarty->assign('nobots', true); - $smarty->assign('nofollow', true); - return; - } - $attributes[] = $attr_id; - } - break; - case 'id_feature': - foreach ($val as $feat) - { - $feat_id = preg_replace('/_\d+$/', '', $feat); - if (in_array($feat_id, $features) || in_array(array('id_feature' => $feat_id), $feature_list)) - { - $smarty->assign('nobots', true); - $smarty->assign('nofollow', true); - return; - } - $features[] = $feat_id; - } - break; - default: - if (in_array($type, $blacklist)) - { - if (count($val)) - { - $smarty->assign('nobots', true); - $smarty->assign('nofollow', true); - return; - } - } - elseif (count($val) > 1) - { - $smarty->assign('nobots', true); - $smarty->assign('nofollow', true); - return; - } - break; - } - } - } - - public function hookFooter($params) - { - // No filters => module disable - if ($filter_block = $this->getFilterBlock($this->getSelectedFilters())) - if ($filter_block['nbr_filterBlocks'] == 0) - return false; - - if (Dispatcher::getInstance()->getController() == 'category') - return ' - '; - } - - public function hookCategoryAddition($params) - { - $this->rebuildLayeredCache(array(), array((int)$params['category']->id)); - } - - public function hookCategoryUpdate($params) - { - /* The category status might (active, inactive) have changed, we have to update the layered cache table structure */ - if (isset($params['category']) && !$params['category']->active) - $this->hookCategoryDeletion($params); - } - - public function hookCategoryDeletion($params) - { - $layered_filter_list = Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS('SELECT * FROM '._DB_PREFIX_.'layered_filter'); - foreach ($layered_filter_list as $layered_filter) - { - $data = Tools::unSerialize($layered_filter['filters']); - if (in_array((int)$params['category']->id, $data['categories'])) - { - unset($data['categories'][array_search((int)$params['category']->id, $data['categories'])]); - Db::getInstance()->execute('UPDATE `'._DB_PREFIX_.'layered_filter` SET `filters` = \''.pSQL(serialize($data)).'\' WHERE `id_layered_filter` = '.(int)$layered_filter['id_layered_filter'].''); - } - } - $this->buildLayeredCategories(); + return str_replace('"', '"', $ret); } public function getContent() { global $cookie; - - $html = ''; + $message = ''; if (Tools::isSubmit('SubmitFilter')) { if (!Tools::getValue('layered_tpl_name')) - $html .= $this->displayError($this->l('Filter template name required (cannot be empty)')); + $message = $this->displayError($this->l('Filter template name required (cannot be empty)')); + elseif (!Tools::getValue('categoryBox')) + $message = $this->displayError($this->l('You must select at least a category')); else { - if (isset($_POST['id_layered_filter']) && $_POST['id_layered_filter']) + if (Tools::getValue('id_layered_filter')) { - Db::getInstance()->execute('DELETE FROM '._DB_PREFIX_.'layered_filter WHERE id_layered_filter = '.(int)Tools::getValue('id_layered_filter')); + Db::getInstance()->execute(' + DELETE FROM '._DB_PREFIX_.'layered_filter + WHERE id_layered_filter = '.(int)Tools::getValue('id_layered_filter') + ); $this->buildLayeredCategories(); } if (Tools::getValue('scope') == 1) { Db::getInstance()->execute('TRUNCATE TABLE '._DB_PREFIX_.'layered_filter'); - $categories = Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS('SELECT id_category FROM '._DB_PREFIX_.'category'); + $categories = Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS(' + SELECT id_category + FROM '._DB_PREFIX_.'category' + ); + foreach ($categories as $category) $_POST['categoryBox'][] = (int)$category['id_category']; } - $id_layered_filter = (int)$_POST['id_layered_filter']; + $id_layered_filter = (int)Tools::getValue('id_layered_filter'); + if (!$id_layered_filter) $id_layered_filter = (int)Db::getInstance()->Insert_ID(); $shop_list = array(); + if (isset($_POST['checkBoxShopAsso_layered_filter'])) { foreach ($_POST['checkBoxShopAsso_layered_filter'] as $id_shop => $row) @@ -1515,6 +1365,11 @@ class BlockLayered extends Module else $shop_list = array(Context::getContext()->shop->id); + Db::getInstance()->execute(' + DELETE FROM '._DB_PREFIX_.'layered_filter_shop + WHERE `id_layered_filter` = '.(int)$id_layered_filter + ); + if (count($_POST['categoryBox'])) { /* Clean categoryBox before use */ @@ -1523,11 +1378,13 @@ class BlockLayered extends Module $category_box_tmp = (int)$category_box_tmp; $filter_values = array(); + foreach ($_POST['categoryBox'] as $idc) $filter_values['categories'][] = (int)$idc; - $filter_values['shop_list'] = $shop_list; + $filter_values['shop_list'] = $shop_list; $values = false; + foreach ($_POST['categoryBox'] as $id_category_layered) { foreach ($_POST as $key => $value) @@ -1536,6 +1393,7 @@ class BlockLayered extends Module $values = true; $type = 0; $limit = 0; + if (Tools::getValue($key.'_filter_type')) $type = Tools::getValue($key.'_filter_type'); if (Tools::getValue($key.'_filter_show_limit')) @@ -1548,24 +1406,29 @@ class BlockLayered extends Module } } - Db::getInstance()->execute('DELETE FROM '._DB_PREFIX_.'layered_filter_shop WHERE `id_layered_filter` = '.(int)$id_layered_filter); - if (isset($assos)) - foreach ($assos as $asso) - Db::getInstance()->execute('INSERT INTO '._DB_PREFIX_.'layered_filter_shop (`id_layered_filter`, `id_shop`) - VALUES('.$id_layered_filter.', '.(int)$asso['id_shop'].')'); - $values_to_insert = array( 'name' => pSQL(Tools::getValue('layered_tpl_name')), 'filters' => pSQL(serialize($filter_values)), 'n_categories' => (int)count($filter_values['categories']), 'date_add' => date('Y-m-d H:i:s')); + if (isset($_POST['id_layered_filter']) && $_POST['id_layered_filter']) $values_to_insert['id_layered_filter'] = (int)Tools::getValue('id_layered_filter'); Db::getInstance()->autoExecute(_DB_PREFIX_.'layered_filter', $values_to_insert, 'INSERT'); + $id_layered_filter = (int)Db::getInstance()->Insert_ID(); + + if (isset($assos)) + foreach ($assos as $asso) + Db::getInstance()->execute(' + INSERT INTO '._DB_PREFIX_.'layered_filter_shop (`id_layered_filter`, `id_shop`) + VALUES('.$id_layered_filter.', '.(int)$asso['id_shop'].')' + ); + + $this->buildLayeredCategories(); - $html .= $this->displayConfirmation($this->l('Your filter').' "'.Tools::safeOutput(Tools::getValue('layered_tpl_name')).'" '. + $message = $this->displayConfirmation($this->l('Your filter').' "'.Tools::safeOutput(Tools::getValue('layered_tpl_name')).'" '. ((isset($_POST['id_layered_filter']) && $_POST['id_layered_filter']) ? $this->l('was updated successfully.') : $this->l('was added successfully.'))); } } @@ -1582,726 +1445,141 @@ class BlockLayered extends Module Configuration::updateValue('PS_LAYERED_FILTER_INDEX_MNF', (int)Tools::getValue('ps_layered_filter_index_manufacturer')); Configuration::updateValue('PS_LAYERED_FILTER_INDEX_CAT', (int)Tools::getValue('ps_layered_filter_index_category')); - $html .= ' -
'.$this->l('Settings saved successfully').'
'; + $message = '
'.$this->l('Settings saved successfully').'
'; } - else if (isset($_GET['deleteFilterTemplate'])) + else if (Tools::getValue('deleteFilterTemplate')) { $layered_values = Db::getInstance(_PS_USE_SQL_SLAVE_)->getValue(' - SELECT filters - FROM '._DB_PREFIX_.'layered_filter - WHERE id_layered_filter = '.(int)$_GET['id_layered_filter']); + SELECT filters + FROM '._DB_PREFIX_.'layered_filter + WHERE id_layered_filter = '.(int)Tools::getValue('id_layered_filter') + ); if ($layered_values) { - Db::getInstance()->execute('DELETE FROM '._DB_PREFIX_.'layered_filter WHERE id_layered_filter = '.(int)$_GET['id_layered_filter'].' LIMIT 1'); + Db::getInstance()->execute(' + DELETE FROM '._DB_PREFIX_.'layered_filter + WHERE id_layered_filter = '.(int)Tools::getValue('id_layered_filter').' LIMIT 1' + ); $this->buildLayeredCategories(); - - $html .= $this->displayConfirmation($this->l('Filter template deleted, categories updated (reverted to default Filter template).')); + $message = $this->displayConfirmation($this->l('Filter template deleted, categories updated (reverted to default Filter template).')); } else - $html .= $this->displayError($this->l('Filter template not found')); + $message = $this->displayError($this->l('Filter template not found')); } - - $html .= ' - - -
-

'.$this->l('Indexes and caches').'

- '; - - if (!Configuration::getGlobalValue('PS_LAYERED_INDEXED')) - $html .= ' - '; - $category_ist = array(); - foreach (Db::getInstance()->executeS('SELECT id_category FROM `'._DB_PREFIX_.'category`') as $category) - if ($category['id_category'] != 1) - $category_ist[] = $category['id_category']; + $category_box = array(); + $attribute_groups = Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS(' + SELECT ag.id_attribute_group, ag.is_color_group, agl.name, COUNT(DISTINCT(a.id_attribute)) n + FROM '._DB_PREFIX_.'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)$cookie->id_lang.' + GROUP BY ag.id_attribute_group' + ); - $domain = Tools::getProtocol(Tools::usingSecureMode()).$_SERVER['HTTP_HOST']; + $features = Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS(' + SELECT fl.id_feature, fl.name, COUNT(DISTINCT(fv.id_feature_value)) n + FROM '._DB_PREFIX_.'feature_lang fl + LEFT JOIN '._DB_PREFIX_.'feature_value fv ON (fv.id_feature = fl.id_feature) + WHERE (fv.custom IS NULL OR fv.custom = 0) AND fl.id_lang = '.(int)$cookie->id_lang.' + GROUP BY fl.id_feature' + ); - $html .= '
-
'.$this->l('You can set a cron job that will rebuild price index using the following URL:').'
'. - $domain.__PS_BASE_URI__.'modules/blocklayered/blocklayered-price-indexer.php'.'?token='.substr(Tools::encrypt('blocklayered/index'), 0, 10).'&full=1 -
-
'.$this->l('You can set a cron job that will rebuild URL index using the following URL:').'
'. - $domain.__PS_BASE_URI__.'modules/blocklayered/blocklayered-url-indexer.php'.'?token='.substr(Tools::encrypt('blocklayered/index'), 0, 10).'&truncate=1 -
-
'.$this->l('You can set a cron job that will rebuild attribute index using the following URL:').'
'. - $domain.__PS_BASE_URI__.'modules/blocklayered/blocklayered-attribute-indexer.php'.'?token='.substr(Tools::encrypt('blocklayered/index'), 0, 10).' -
- '.$this->l('A nightly rebuild is recommended.').' - -
-
-
-

'.$this->l('Existing filter templates').'

'; - - $filters_templates = Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS('SELECT * FROM '._DB_PREFIX_.'layered_filter ORDER BY date_add DESC'); - if (count($filters_templates)) - { - $html .= '

'.sprintf($this->l('%s filter templates are configured:'), count($filters_templates)).'

- - - - - - - - - - '; - - foreach ($filters_templates as $filters_template) - { - /* Clean request URI first */ - $_SERVER['REQUEST_URI'] = preg_replace('/&deleteFilterTemplate=[0-9]*&id_layered_filter=[0-9]*/', '', $_SERVER['REQUEST_URI']); - - $html .= ' - - - - - - - '; - } - - $html .= ' -
'.$this->l('ID').''.$this->l('Name').''.$this->l('Categories').''.$this->l('Created on').''.$this->l('Actions').'
'.(int)$filters_template['id_layered_filter'].''.$filters_template['name'].''.(int)$filters_template['n_categories'].''.Tools::displayDate($filters_template['date_add'],null , true).' - -
'; - } - else - $html .= $this->l('No filter template found.'); - - $html .= ' -
-
-

'.$this->l('Build your own filter template').'

-
'; - - $html .= ' -

'.$this->l('Step 1/3 - Select categories').'

-
-
-
- -
-

- - -

-

- - -

-
-
'; - - $shops = Shop::getShops(true, null, true); - if (count($shops) > 1) + if (Shop::isFeatureActive() && count(Shop::getShops(true, null, true)) > 1) { $helper = new HelperForm(); - $helper->id = null; + $helper->id = Tools::getValue('id_layered_filter', null); $helper->table = 'layered_filter'; $helper->identifier = 'id_layered_filter'; - - if (Shop::isFeatureActive()) - { - $html .= '
- -
'.$helper->renderAssoShop().'
-
'; - } + $this->context->smarty->assign('asso_shops', $helper->renderAssoShop()); } - $html .= '
- -
-
-

'.$this->l('Categories using this template').'

-
    -
  1. '.$this->l('Select one ore more category using this filter template').'
  2. -
  3. '.$this->l('Press "Save this selection" or close the window to save').'
  4. -
'; + $tree_categories_helper = new HelperTreeCategories('categories-treeview'); + $tree_categories_helper->setRootCategory((Shop::getContext() == Shop::CONTEXT_SHOP ? Category::getRootCategory()->id_category : 0)) + ->setUseCheckBox(true); - $selected_cat = array(); - // Translations are not automatic for the moment ;) - if (Shop::getContext() == Shop::CONTEXT_SHOP) - { - $root_category = Category::getRootCategory(); - $root_category = array('id_category' => $root_category->id_category, 'name' => $root_category->name); - } - else - $root_category = array('id_category' => '0', 'name' => $this->l('Root')); + $module_url = Tools::getProtocol(Tools::usingSecureMode()).$_SERVER['HTTP_HOST'].$this->getPathUri(); - $helper = new Helper(); - $html .= $helper->renderCategoryTree(null, $selected_cat, 'categoryBox', false, false, array(), true); - - $html .= ' -
- -
-
- -
 
-
-
'.$this->l('Filter template name required (cannot be empty)').'
-

'.$this->l('Step 3/3 - Name your template').'

-
-

'.$this->l('Template name:').' ('.$this->l('only as a reminder').')

-
'.$this->l('No filters selected, the blocklayered will be disable for the categories seleted.').'
- -
- - -
-
-
-

'.$this->l('Configuration').'

-
-
- -
-
-
- - - - - - - -
-
-
-
-
- -
-
-
- - - - - - - -
-
-
-
-
- -
-
-
- - - - - - - -
-
-
-
-
- -
- -
-
-
- -
-
-
- - - - - - - -
-
-
-
-
- -
-
-
- - - - - - - -
-
-
-
-
- -
-
-
- - - - - - - -
-
-
-
-
- -
-
-
- - - - - - - -
-
-
-
-
- -
-
-
- - - - - - - -
-
-
-
-
-
- -
-
-
-
'; - - return $html; + return $this->display(__FILE__, 'views/templates/admin/view.tpl'); + } } private function getSelectedFilters() @@ -2649,10 +1927,12 @@ class BlockLayered extends Module $parent = new Category((int)$id_parent, $id_lang); /* Get the filters for the current category */ - $filters = Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS('SELECT * FROM '._DB_PREFIX_.'layered_category + $filters = Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS(' + SELECT * FROM '._DB_PREFIX_.'layered_category WHERE id_category = '.(int)$id_parent.' AND id_shop = '.$id_shop.' - GROUP BY `type`, id_value ORDER BY position ASC'); + GROUP BY `type`, id_value ORDER BY position ASC' + ); // Remove all empty selected filters foreach ($selected_filters as $key => $value) switch ($key) @@ -3543,371 +2823,6 @@ class BlockLayered extends Module return array('where' => $query_filters); } - public function ajaxCallBackOffice($category_box = array(), $id_layered_filter = null) - { - global $cookie; - - if (!empty($id_layered_filter)) - { - $layered_filter = Db::getInstance(_PS_USE_SQL_SLAVE_)->getRow('SELECT * FROM '._DB_PREFIX_.'layered_filter WHERE id_layered_filter = '.(int)$id_layered_filter); - if ($layered_filter && isset($layered_filter['filters']) && !empty($layered_filter['filters'])) - $layered_values = Tools::unSerialize($layered_filter['filters']); - if (isset($layered_values['categories']) && count($layered_values['categories'])) - foreach ($layered_values['categories'] as $id_category) - $category_box[] = (int)$id_category; - } - - /* Clean categoryBox before use */ - if (isset($category_box) && is_array($category_box)) - foreach ($category_box as &$value) - $value = (int)$value; - else - $category_box = array(); - - $attribute_groups = Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS(' - SELECT ag.id_attribute_group, ag.is_color_group, agl.name, COUNT(DISTINCT(a.id_attribute)) n - FROM '._DB_PREFIX_.'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) - '.(count($category_box) ? ' - 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)'. - Shop::addSqlAssociation('product_attribute', 'pa').' - LEFT JOIN '._DB_PREFIX_.'category_product cp ON (cp.id_product = pa.id_product)' : '').' - WHERE agl.id_lang = '.(int)$cookie->id_lang. - (count($category_box) ? ' AND cp.id_category IN ('.implode(',', $category_box).')' : '').' - GROUP BY ag.id_attribute_group'); - - $features = Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS(' - SELECT fl.id_feature, fl.name, COUNT(DISTINCT(fv.id_feature_value)) n - FROM '._DB_PREFIX_.'feature_lang fl - LEFT JOIN '._DB_PREFIX_.'feature_value fv ON (fv.id_feature = fl.id_feature) - '.(count($category_box) ? ' - LEFT JOIN '._DB_PREFIX_.'feature_product fp ON (fp.id_feature = fv.id_feature) - LEFT JOIN '._DB_PREFIX_.'category_product cp ON (cp.id_product = fp.id_product)' : '').' - WHERE (fv.custom IS NULL OR fv.custom = 0) AND fl.id_lang = '.(int)$cookie->id_lang. - (count($category_box) ? ' AND cp.id_category IN ('.implode(',', $category_box).')' : '').' - GROUP BY fl.id_feature'); - - $n_elements = count($attribute_groups) + count($features) + 4; - if ($n_elements > 20) - $n_elements = 20; - - $html = ' -
-

'.$this->l('Available filters').' (0)

-
    -
      -
    • - - '.$this->l('Sub-categories filter').' - - - -
    • -
    -
      -
    • - - '.$this->l('Product stock filter').' - - - -
    • -
    -
      -
    • - - - '.$this->l('Product condition filter').' - - - -
    • -
    -
      -
    • - - - '.$this->l('Product manufacturer filter').' - - - -
    • -
    -
      -
    • - - - '.$this->l('Product weight filter (slider)').' - - - -
    • -
    -
      -
    • - - - '.$this->l('Product price filter (slider)').' - - - -
    • -
    '; - - if (count($attribute_groups)) - { - $html .= '
      '; - foreach ($attribute_groups as $attribute_group) - $html .= ' -
    • - - - - '.($attribute_group['n'] > 1 ? sprintf($this->l('Attribute group: %1$s (%2$d attributes)'), $attribute_group['name'], $attribute_group['n']) : sprintf($this->l('Attribute group: %1$s (%2$d attribute)'), $attribute_group['name'], $attribute_group['n'])).')'. - ($attribute_group['is_color_group'] ? ' ' : '').' - - - -
    • '; - $html .= '
    '; - } - - if (count($features)) - { - $html .= '
      '; - foreach ($features as $feature) - $html .= ' -
    • - - - - '.($feature['n'] > 1 ? sprintf($this->l('Feature: %1$s (%2$d values)'), $feature['name'], $feature['n']) : sprintf($this->l('Feature: %1$s (%2$d value)'), $feature['name'], $feature['n'])).') - - - -
    • '; - $html .= '
    '; - } - - $html .= ' -
    '; - - if (isset($layered_values)) - { - $html .= ' - '; - } - - if (!empty($id_layered_filter)) - { - if (Shop::isFeatureActive() && Shop::getContext() != Shop::CONTEXT_ALL) - { - $shops = Shop::getShops(true, null, true); - if (count($shops) > 1) - { - $helper = new HelperForm(); - $helper->id = (int)$id_layered_filter; - $helper->table = 'layered_filter'; - $helper->identifier = 'id_layered_filter'; - $helper->base_folder = Tools::getValue('base_folder').'/themes/default/template/helpers/form/'; - - $html .= ' -
    '.$helper->renderAssoShop(false, Tools::getValue('base_folder').'/themes/default/template/helpers/tree/').'
    - '; - } - } - } - - return $html; - } - public function ajaxCall() { global $smarty, $cookie; diff --git a/modules/blocklayered/views/css/blocklayered.css b/modules/blocklayered/css/blocklayered_admin.css similarity index 100% rename from modules/blocklayered/views/css/blocklayered.css rename to modules/blocklayered/css/blocklayered_admin.css diff --git a/modules/blocklayered/css/blocklayered_admin_bt.css b/modules/blocklayered/css/blocklayered_admin_bt.css new file mode 100644 index 000000000..30172b768 --- /dev/null +++ b/modules/blocklayered/css/blocklayered_admin_bt.css @@ -0,0 +1,25 @@ +.bootstrap .filter_list .filter_list_item { + display: table; + width: 100%; + padding: 5px 0; + margin-bottom: 4px; + background-color: white; + -webkit-box-shadow: rgba(0, 0, 0, 0.3) 0 0 3px, rgba(0, 0, 0, 0.1) 0 -2px 0 inset; + box-shadow: rgba(0, 0, 0, 0.3) 0 0 3px, rgba(0, 0, 0, 0.1) 0 -2px 0 inset; + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + -ms-border-radius: 3px; + -o-border-radius: 3px; + border-radius: 3px; +} + +.bootstrap .filter_panel { + min-height: 20px; + padding: 7px 7px 0px 7px; + margin-bottom: 20px; + background-color: #ebebeb; + border: 1px solid #d9d9d9; + border-radius: 3px; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05); +} \ No newline at end of file diff --git a/modules/blocklayered/js/blocklayered_admin.js b/modules/blocklayered/js/blocklayered_admin.js new file mode 100644 index 000000000..d23a9ee3e --- /dev/null +++ b/modules/blocklayered/js/blocklayered_admin.js @@ -0,0 +1,219 @@ +function checkForm() +{ + var is_category_selected = false; + var is_filter_selected = false; + + $('#categories-treeview input[type=checkbox]').each( + function() + { + if ($(this).prop('checked')) + { + is_category_selected = true; + return false; + } + } + ); + + $('.filter_list_item input[type=checkbox]').each( + function() + { + if ($(this).prop('checked')) + { + is_filter_selected = true; + return false; + } + } + ); + + if (!is_category_selected) + { + alert(translations['no_selected_categories']); + $('#categories-treeview input[type=checkbox]').first().focus(); + return false; + } + + if (!is_filter_selected) + { + alert(translations['no_selected_filters']); + $('#filter_list_item input[type=checkbox]').first().focus(); + return false; + } + + + return true; +} + +$(document).ready( + function() + { + $('.ajaxcall').click( + function() + { + if (this.legend == undefined) + this.legend = $(this).html(); + + if (this.running == undefined) + this.running = false; + + if (this.running == true) + return false; + + $('.ajax-message').hide(); + this.running = true; + + if (typeof(this.restartAllowed) == 'undefined' || this.restartAllowed) + { + $(this).html(this.legend+translations['in_progress']); + $('#indexing-warning').show(); + } + + this.restartAllowed = false; + var type = $(this).attr('rel'); + + $.ajax( + { + url: this.href+'&ajax=1', + context: this, + dataType: 'json', + cache: 'false', + success: function(res) + { + this.running = false; + this.restartAllowed = true; + $('#indexing-warning').hide(); + $(this).html(this.legend); + + if (type == 'price') + $('#ajax-message-ok span').html(translations['url_indexation_finished']); + else + $('#ajax-message-ok span').html(translations['attribute_indexation_finished']); + + $('#ajax-message-ok').show(); + return; + }, + error: function(res) + { + this.restartAllowed = true; + $('#indexing-warning').hide(); + + if (type == 'price') + $('#ajax-message-ko span').html(translations['url_indexation_failed']); + else + $('#ajax-message-ko span').html(translations['attribute_indexation_failed']); + + $('#ajax-message-ko').show(); + $(this).html(this.legend); + this.running = false; + } + } + ); + return false; + }); + + $('.ajaxcall-recurcive').each( + function(it, elm) + { + $(elm).click( + function() + { + if (this.cursor == undefined) + this.cursor = 0; + + if (this.legend == undefined) + this.legend = $(this).html(); + + if (this.running == undefined) + this.running = false; + + if (this.running == true) + return false; + + $('.ajax-message').hide(); + + this.running = true; + + if (typeof(this.restartAllowed) == 'undefined' || this.restartAllowed) + { + $(this).html(this.legend+translations['in_progress']); + $('#indexing-warning').show(); + } + + this.restartAllowed = false; + + $.ajax( + { + url: this.href+'&ajax=1&cursor='+this.cursor, + context: this, + dataType: 'json', + cache: 'false', + success: function(res) + { + this.running = false; + if (res.result) + { + this.cursor = 0; + $('#indexing-warning').hide(); + $(this).html(this.legend); + $('#ajax-message-ok span').html(translations['price_indexation_finished']); + $('#ajax-message-ok').show(); + return; + } + this.cursor = parseInt(res.cursor); + $(this).html(this.legend+translations['price_indexation_in_progress'].replace('%s', res.count)); + $(this).click(); + }, + error: function(res) + { + this.restartAllowed = true; + $('#indexing-warning').hide(); + $('#ajax-message-ko span').html(translations['price_indexation_failed']); + $('#ajax-message-ko').show(); + $(this).html(this.legend); + + this.cursor = 0; + this.running = false; + } + }); + return false; + } + ); + } + ); + + if (typeof PS_LAYERED_INDEXED !== 'undefined' && PS_LAYERED_INDEXED) + { + $('#url-indexe').click(); + $('#full-index').click(); + } + + $('.sortable').sortable( + { + forcePlaceholderSize: true + }); + + $('.filter_list_item input[type=checkbox]').click( + function() + { + var current_selected_filters_count = parseInt($('#selected_filters').html()); + + if ($(this).prop('checked')) + $('#selected_filters').html(current_selected_filters_count+1); + else + $('#selected_filters').html(current_selected_filters_count-1); + } + ); + + if (typeof filters !== 'undefined') + { + filters = JSON.parse(filters); + + for (filter in filters) + { + $('#'+filter).attr("checked","checked"); + $('#selected_filters').html(parseInt($('#selected_filters').html())+1); + $('select[name="'+filter+'_filter_type"]').val(filters[filter].filter_type); + $('select[name="'+filter+'_filter_show_limit"]').val(filters[filter].filter_show_limit); + } + } + } +); \ No newline at end of file diff --git a/modules/blocklayered/js/index.php b/modules/blocklayered/js/index.php new file mode 100644 index 000000000..5d522bb3a --- /dev/null +++ b/modules/blocklayered/js/index.php @@ -0,0 +1,35 @@ + +* @copyright 2007-2013 PrestaShop SA +* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) +* International Registered Trademark & Property of PrestaShop SA +*/ + +header("Expires: Mon, 26 Jul 1997 05:00:00 GMT"); +header("Last-Modified: ".gmdate("D, d M Y H:i:s")." GMT"); + +header("Cache-Control: no-store, no-cache, must-revalidate"); +header("Cache-Control: post-check=0, pre-check=0", false); +header("Pragma: no-cache"); + +header("Location: ../../"); +exit; \ No newline at end of file diff --git a/modules/blocklayered/logo.gif b/modules/blocklayered/logo.gif index 659aace81..40df30a4c 100644 Binary files a/modules/blocklayered/logo.gif and b/modules/blocklayered/logo.gif differ diff --git a/modules/blocklayered/upgrade/index.php b/modules/blocklayered/upgrade/index.php new file mode 100644 index 000000000..5d522bb3a --- /dev/null +++ b/modules/blocklayered/upgrade/index.php @@ -0,0 +1,35 @@ + +* @copyright 2007-2013 PrestaShop SA +* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) +* International Registered Trademark & Property of PrestaShop SA +*/ + +header("Expires: Mon, 26 Jul 1997 05:00:00 GMT"); +header("Last-Modified: ".gmdate("D, d M Y H:i:s")." GMT"); + +header("Cache-Control: no-store, no-cache, must-revalidate"); +header("Cache-Control: post-check=0, pre-check=0", false); +header("Pragma: no-cache"); + +header("Location: ../../"); +exit; \ No newline at end of file diff --git a/modules/blocklayered/views/css/blocklayered_bt.css b/modules/blocklayered/views/css/blocklayered_bt.css deleted file mode 100644 index c468f04cd..000000000 --- a/modules/blocklayered/views/css/blocklayered_bt.css +++ /dev/null @@ -1,21 +0,0 @@ -#error-filter-name { display: none; } -#layered_container_left ul, #layered_container_right ul { list-style-type: none; padding-left: 0px; } -.ui-effects-transfer { border: 1px solid #CCC; } -.ui-state-highlight { height: 1.5em; line-height: 1.2em; } -ul#selected_filters, #layered_container_right ul { list-style-type: none; margin: 0; padding: 0; } -ul#selected_filters li, #layered_container_right ul li { font-size: 11px; padding: 8px 9px 7px 20px; height: 38px; margin-bottom: 5px; } -ul#selected_filters li span.ui-icon { position: absolute; margin-top: -2px; margin-left: -18px; } -#layered_container_right ul li span { display: none; } -#layered_container_right ul li { padding-left: 8px; position: relative; } -#layered_container_left ul li { cursor: move; position: relative; } -#layered-cat-counter { display: none; } -#layered-step-2, #layered-step-3 { display: none; } -#layered-step-2 h3 { margin-top: 0; } -#table-filter-templates tr th, #table-filter-templates tr td { text-align: center; } -.filter_type { width: 120px; position: absolute; right: 130px; top: 5px;} -.filter_show_limit { position: absolute; width: 120px; right: 5px; top: 5px; } -#layered-step-3 .alert { width: auto; } -#fancybox-content { - height: 400px !important; - overflow: auto !important; -} \ No newline at end of file diff --git a/modules/blocklayered/views/index.php b/modules/blocklayered/views/index.php new file mode 100644 index 000000000..5d522bb3a --- /dev/null +++ b/modules/blocklayered/views/index.php @@ -0,0 +1,35 @@ + +* @copyright 2007-2013 PrestaShop SA +* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) +* International Registered Trademark & Property of PrestaShop SA +*/ + +header("Expires: Mon, 26 Jul 1997 05:00:00 GMT"); +header("Last-Modified: ".gmdate("D, d M Y H:i:s")." GMT"); + +header("Cache-Control: no-store, no-cache, must-revalidate"); +header("Cache-Control: post-check=0, pre-check=0", false); +header("Pragma: no-cache"); + +header("Location: ../../"); +exit; \ No newline at end of file diff --git a/modules/blocklayered/views/templates/admin/add.tpl b/modules/blocklayered/views/templates/admin/add.tpl new file mode 100644 index 000000000..61dc8709a --- /dev/null +++ b/modules/blocklayered/views/templates/admin/add.tpl @@ -0,0 +1,373 @@ +{$message} +
    +

    {l s='New filters template' mod='blocklayered'}

    +
    + + +
    + +
    + +

    {l s='Only as a reminder' mod='blockfacette'}

    +
    +
    +
    + +
    + {$categories_tree} +
    +
    + {if isset($asso_shops)} +
    + +
    {$asso_shops}
    +
    + {/if} +
    + +
    +
    +
    + {l s='Total filters: %s'|sprintf:$total_filters mod='blocklayered'} +
    +
    +
      +
    • +
      + +
      +
      +

      {l s='Sub-categories filter' mod='blockfacette'}

      +
      +
      + +
      + +
      +
      +
      + +
      + +
      +
      +
    • +
    • +
      + +
      +
      + {l s='Product stock filter' mod='blockfacette'} +
      +
      + +
      + +
      +
      +
      + +
      + +
      +
      +
    • +
    • +
      + +
      +
      + {l s='Product condition filter' mod='blockfacette'} +
      +
      + +
      + +
      +
      +
      + +
      + +
      +
      +
    • +
    • +
      + +
      +
      + {l s='Product manufacturer filter' mod='blockfacette'} +
      +
      + +
      + +
      +
      +
      + +
      + +
      +
      +
    • +
    • +
      + +
      +
      + {l s='Product weight filter (slider)' mod='blockfacette'} +
      +
      + +
      + +
      +
      +
      + +
      + +
      +
      +
    • +
    • +
      + +
      +
      + {l s='Product price filter (slider)' mod='blockfacette'} +
      +
      + +
      + +
      +
      +
      + +
      + +
      +
      +
    • + {if $attribute_groups|count > 0} + {foreach $attribute_groups as $attribute_group} +
    • +
      + +
      +
      +

      + {if $attribute_group['n'] > 1} + {l s='Attribute group: %1$s (%2$d attributes)'|sprintf:$attribute_group['name']:$attribute_group['n'] mod='blockfacette'} + {else} + {l s='Attribute group: %1$s (%2$d attribute)'|sprintf:$attribute_group['name']:$attribute_group['n'] mod='blockfacette'} + {/if} + {if $attribute_group['is_color_group']} + + {/if} +

      +
      +
      + +
      + +
      +
      +
      + +
      + +
      +
      +
    • + {/foreach} + {/if} + + {if $features|count > 0} + {foreach $features as $feature} +
    • +
      + +
      +
      +

      + {if $feature['n'] > 1}{l s='Feature: %1$s (%2$d values)'|sprintf:$feature['name']:$feature['n'] mod='blockfacette'}{else}{l s='Feature: %1$s (%2$d value)'|sprintf:$feature['name']:$feature['n'] mod='blockfacette'}{/if} +

      +
      +
      + +
      + +
      +
      +
      + +
      + +
      +
      +
    • + {/foreach} + {/if} +
    +
    +
    +
    +
    + +
    +
    + + \ No newline at end of file diff --git a/modules/blocklayered/views/templates/admin/index.php b/modules/blocklayered/views/templates/admin/index.php new file mode 100644 index 000000000..db8997e78 --- /dev/null +++ b/modules/blocklayered/views/templates/admin/index.php @@ -0,0 +1,35 @@ + +* @copyright 2007-2013 PrestaShop SA +* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) +* International Registered Trademark & Property of PrestaShop SA +*/ + +header("Expires: Mon, 26 Jul 1997 05:00:00 GMT"); +header("Last-Modified: ".gmdate("D, d M Y H:i:s")." GMT"); + +header("Cache-Control: no-store, no-cache, must-revalidate"); +header("Cache-Control: post-check=0, pre-check=0", false); +header("Pragma: no-cache"); + +header("Location: ../../../../"); +exit; \ No newline at end of file diff --git a/modules/blocklayered/views/templates/admin/view.tpl b/modules/blocklayered/views/templates/admin/view.tpl new file mode 100644 index 000000000..0d2a45d05 --- /dev/null +++ b/modules/blocklayered/views/templates/admin/view.tpl @@ -0,0 +1,291 @@ +{$message} + + +
    +

    {l s='Indexes and caches' mod='blocklayered'}

    + + +
    +
    + {l s='You can set a cron job that will rebuild price index using the following URL:' mod='blocklayered'} +
    + {$price_indexer_url} +
    +
    + {l s='You can set a cron job that will rebuild attribute index using the following URL:' mod='blocklayered'} +
    + {$attribute_indexer_url} +
    +
    + {l s='You can set a cron job that will rebuild URL index using the following URL:' mod='blocklayered'} +
    + {$url_indexer_url} +
    +
    +
    +
    {l s='A nightly rebuild is recommended.' mod='blocklayered'}
    +
    +
    +
    +

    {l s='Filters templates' mod='blocklayered'}{$filters_templates|count}

    + {if $filters_templates|count > 0} +
    + + + + + + + + + + + + {foreach $filters_templates as $template} + + + + + + + + {/foreach} + +
    {l s='ID' mod='blocklayered'}{l s='Name' mod='blocklayered'}{l s='Categories' mod='blocklayered'}{l s='Created on' mod='blocklayered'}{l s='Actions' mod='blocklayered'}
    {(int)$template['id_layered_filter']}{$template['name']}{(int)$template['n_categories']}{Tools::displayDate($template['date_add'],null , true)} + +
    +
     
    +
    + {else} +
    {l s='No filter template found.' mod='blocklayered'}
    + {/if} + +
    +
    +

    {l s='Configuration' mod='blocklayered'}

    +
    +
    + +
    +
    +
    + + + + + + + +
    +
    +
    +
    +
    + +
    +
    +
    + + + + + + + +
    +
    +
    +
    +
    + +
    +
    +
    + + + + + + + +
    +
    +
    +
    +
    + +
    + +
    +
    +
    + +
    +
    +
    + + + + + + + +
    +
    +
    +
    +
    + +
    +
    +
    + + + + + + + +
    +
    +
    +
    +
    + +
    +
    +
    + + + + + + + +
    +
    +
    +
    +
    + +
    +
    +
    + + + + + + + +
    +
    +
    +
    +
    + +
    +
    +
    + + + + + + + +
    +
    +
    +
    +
    +
    + +
    +
    +
    +
    + + \ No newline at end of file diff --git a/modules/blocklayered/views/templates/front/index.php b/modules/blocklayered/views/templates/front/index.php new file mode 100644 index 000000000..db8997e78 --- /dev/null +++ b/modules/blocklayered/views/templates/front/index.php @@ -0,0 +1,35 @@ + +* @copyright 2007-2013 PrestaShop SA +* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) +* International Registered Trademark & Property of PrestaShop SA +*/ + +header("Expires: Mon, 26 Jul 1997 05:00:00 GMT"); +header("Last-Modified: ".gmdate("D, d M Y H:i:s")." GMT"); + +header("Cache-Control: no-store, no-cache, must-revalidate"); +header("Cache-Control: post-check=0, pre-check=0", false); +header("Pragma: no-cache"); + +header("Location: ../../../../"); +exit; \ No newline at end of file diff --git a/modules/blocklayered/views/templates/hook/attribute_form.tpl b/modules/blocklayered/views/templates/hook/attribute_form.tpl new file mode 100644 index 000000000..5430bbdad --- /dev/null +++ b/modules/blocklayered/views/templates/hook/attribute_form.tpl @@ -0,0 +1,82 @@ +{* +* 2007-2013 PrestaShop +* +* NOTICE OF LICENSE +* +* This source file is subject to the Academic Free License (AFL 3.0) +* that is bundled with this package in the file LICENSE.txt. +* It is also available through the world-wide-web at this URL: +* http://opensource.org/licenses/afl-3.0.php +* If you did not receive a copy of the license and are unable to +* obtain it through the world-wide-web, please send an email +* to license@prestashop.com so we can send you a copy immediately. +* +* DISCLAIMER +* +* Do not edit or add to this file if you wish to upgrade PrestaShop to newer +* versions in the future. If you wish to customize PrestaShop for your +* needs please refer to http://www.prestashop.com for more information. +* +* @author PrestaShop SA +* @copyright 2007-2013 PrestaShop SA +* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) +* International Registred Trademark & Property of PrestaShop SA +*} +
    + +
    +
    + {foreach $languages as $language} +
    +
    + +
    +
    + + +
    +
    + {/foreach} +
    +

    {l s='Specific URL format in block layered generation' mod='blockfacette'}

    +
    +
    +
    +
    +
    + +
    +
    + {foreach $languages as $language} +
    +
    + +
    +
    + + +
    +
    + {/foreach} +
    +

    {l s='Specific format for meta title' mod='blockfacette'}

    +
    +
    +
    +
    \ No newline at end of file diff --git a/modules/blocklayered/views/templates/hook/attribute_group_form.tpl b/modules/blocklayered/views/templates/hook/attribute_group_form.tpl new file mode 100644 index 000000000..abab05d99 --- /dev/null +++ b/modules/blocklayered/views/templates/hook/attribute_group_form.tpl @@ -0,0 +1,105 @@ +{* +* 2007-2013 PrestaShop +* +* NOTICE OF LICENSE +* +* This source file is subject to the Academic Free License (AFL 3.0) +* that is bundled with this package in the file LICENSE.txt. +* It is also available through the world-wide-web at this URL: +* http://opensource.org/licenses/afl-3.0.php +* If you did not receive a copy of the license and are unable to +* obtain it through the world-wide-web, please send an email +* to license@prestashop.com so we can send you a copy immediately. +* +* DISCLAIMER +* +* Do not edit or add to this file if you wish to upgrade PrestaShop to newer +* versions in the future. If you wish to customize PrestaShop for your +* needs please refer to http://www.prestashop.com for more information. +* +* @author PrestaShop SA +* @copyright 2007-2013 PrestaShop SA +* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) +* International Registred Trademark & Property of PrestaShop SA +*} +
    + +
    +
    + {foreach $languages as $language} +
    +
    + +
    +
    + + +
    +
    + {/foreach} +
    +

    {l s='Specific URL format in block layered generation' mod='blockfacette'}

    +
    +
    +
    +
    +
    + +
    +
    + {foreach $languages as $language} +
    +
    + +
    +
    + + +
    +
    + {/foreach} +
    +

    {l s='Specific format for meta title' mod='blockfacette'}

    +
    +
    +
    +
    +
    + +
    +
    +
    + + + + + + + +
    +
    +
    +
    +

    {l s='Use this attribute in URL generated by the layered navigation module' mod='blockfacette'}

    +
    +
    \ No newline at end of file diff --git a/modules/blocklayered/views/templates/hook/feature_form.tpl b/modules/blocklayered/views/templates/hook/feature_form.tpl new file mode 100644 index 000000000..82b9d550a --- /dev/null +++ b/modules/blocklayered/views/templates/hook/feature_form.tpl @@ -0,0 +1,105 @@ +{* +* 2007-2013 PrestaShop +* +* NOTICE OF LICENSE +* +* This source file is subject to the Academic Free License (AFL 3.0) +* that is bundled with this package in the file LICENSE.txt. +* It is also available through the world-wide-web at this URL: +* http://opensource.org/licenses/afl-3.0.php +* If you did not receive a copy of the license and are unable to +* obtain it through the world-wide-web, please send an email +* to license@prestashop.com so we can send you a copy immediately. +* +* DISCLAIMER +* +* Do not edit or add to this file if you wish to upgrade PrestaShop to newer +* versions in the future. If you wish to customize PrestaShop for your +* needs please refer to http://www.prestashop.com for more information. +* +* @author PrestaShop SA +* @copyright 2007-2013 PrestaShop SA +* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) +* International Registred Trademark & Property of PrestaShop SA +*} +
    + +
    +
    + {foreach $languages as $language} +
    +
    + +
    +
    + + +
    +
    + {/foreach} +
    +

    {l s='Specific URL format in block layered generation' mod='blockfacette'}

    +
    +
    +
    +
    +
    + +
    +
    + {foreach $languages as $language} +
    +
    + +
    +
    + + +
    +
    + {/foreach} +
    +

    {l s='Specific format for meta title' mod='blockfacette'}

    +
    +
    +
    +
    +
    + +
    +
    +
    + + + + + + + +
    +
    +
    +
    +

    {l s='Use this attribute in URL generated by the layered navigation module' mod='blockfacette'}

    +
    +
    \ No newline at end of file diff --git a/modules/blocklayered/views/templates/hook/feature_value_form.tpl b/modules/blocklayered/views/templates/hook/feature_value_form.tpl new file mode 100644 index 000000000..5430bbdad --- /dev/null +++ b/modules/blocklayered/views/templates/hook/feature_value_form.tpl @@ -0,0 +1,82 @@ +{* +* 2007-2013 PrestaShop +* +* NOTICE OF LICENSE +* +* This source file is subject to the Academic Free License (AFL 3.0) +* that is bundled with this package in the file LICENSE.txt. +* It is also available through the world-wide-web at this URL: +* http://opensource.org/licenses/afl-3.0.php +* If you did not receive a copy of the license and are unable to +* obtain it through the world-wide-web, please send an email +* to license@prestashop.com so we can send you a copy immediately. +* +* DISCLAIMER +* +* Do not edit or add to this file if you wish to upgrade PrestaShop to newer +* versions in the future. If you wish to customize PrestaShop for your +* needs please refer to http://www.prestashop.com for more information. +* +* @author PrestaShop SA +* @copyright 2007-2013 PrestaShop SA +* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) +* International Registred Trademark & Property of PrestaShop SA +*} +
    + +
    +
    + {foreach $languages as $language} +
    +
    + +
    +
    + + +
    +
    + {/foreach} +
    +

    {l s='Specific URL format in block layered generation' mod='blockfacette'}

    +
    +
    +
    +
    +
    + +
    +
    + {foreach $languages as $language} +
    +
    + +
    +
    + + +
    +
    + {/foreach} +
    +

    {l s='Specific format for meta title' mod='blockfacette'}

    +
    +
    +
    +
    \ No newline at end of file diff --git a/modules/blocklayered/views/templates/hook/index.php b/modules/blocklayered/views/templates/hook/index.php new file mode 100644 index 000000000..db8997e78 --- /dev/null +++ b/modules/blocklayered/views/templates/hook/index.php @@ -0,0 +1,35 @@ + +* @copyright 2007-2013 PrestaShop SA +* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) +* International Registered Trademark & Property of PrestaShop SA +*/ + +header("Expires: Mon, 26 Jul 1997 05:00:00 GMT"); +header("Last-Modified: ".gmdate("D, d M Y H:i:s")." GMT"); + +header("Cache-Control: no-store, no-cache, must-revalidate"); +header("Cache-Control: post-check=0, pre-check=0", false); +header("Pragma: no-cache"); + +header("Location: ../../../../"); +exit; \ No newline at end of file diff --git a/modules/blocklayered/views/templates/index.php b/modules/blocklayered/views/templates/index.php new file mode 100644 index 000000000..35add21b6 --- /dev/null +++ b/modules/blocklayered/views/templates/index.php @@ -0,0 +1,35 @@ + +* @copyright 2007-2013 PrestaShop SA +* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) +* International Registered Trademark & Property of PrestaShop SA +*/ + +header("Expires: Mon, 26 Jul 1997 05:00:00 GMT"); +header("Last-Modified: ".gmdate("D, d M Y H:i:s")." GMT"); + +header("Cache-Control: no-store, no-cache, must-revalidate"); +header("Cache-Control: post-check=0, pre-check=0", false); +header("Pragma: no-cache"); + +header("Location: ../../../"); +exit; \ No newline at end of file