GaetanV Posted July 25, 2022 Share Posted July 25, 2022 (edited) Hello, In the faceted module I don't have access to all the product features. I've rebuilt the index, cleared the module and site cache, but the missing features still don't show up. Is there something that can prevent the display of a characteristic or is it a bug? Thank you for your help. Edited July 28, 2022 by GaetanV (see edit history) Link to comment Share on other sites More sharing options...
GaetanV Posted July 28, 2022 Author Share Posted July 28, 2022 (edited) Problem fixed... The faceted module does not allow searching on characteristics that do not have predefined values. To avoid this behavior, you must authorize the module to list the characteristics that do not have default values by overriding the file: modules\ps_facetedsearch\ps_facetedsearch.php For this add the file: override\modules\ps_facetedsearch\ps_facetedsearch.php With this content: <?php class Ps_FacetedsearchOverride extends Ps_Facetedsearch { /** * @var int */ private $psLayeredFullTree; public function getContent() { global $cookie; $message = ''; if (Tools::isSubmit('SubmitFilter')) { if (!Tools::getValue('layered_tpl_name')) { $message = $this->displayError($this->trans('Filter template name required (cannot be empty)', [], 'Modules.Facetedsearch.Admin')); } elseif (!Tools::getValue('categoryBox')) { $message = $this->displayError($this->trans('You must select at least one category.', [], 'Modules.Facetedsearch.Admin')); } else { // Get or generate id $idLayeredFilter = (int) Tools::getValue('id_layered_filter'); if (Tools::getValue('scope')) { $this->getDatabase()->execute('TRUNCATE TABLE ' . _DB_PREFIX_ . 'layered_filter'); $categories = $this->getDatabase()->executeS( 'SELECT id_category FROM ' . _DB_PREFIX_ . 'category' ); foreach ($categories as $category) { $_POST['categoryBox'][] = (int) $category['id_category']; } } // Associate Shops if (isset($_POST['checkBoxShopAsso_layered_filter'])) { $shopList = []; foreach ($_POST['checkBoxShopAsso_layered_filter'] as $idShop => $row) { $assos[] = ['id_shop' => (int) $idShop]; $shopList[] = (int) $idShop; } } else { $shopList = [(int) $this->getContext()->shop->id]; } if (!empty($_POST['categoryBox']) && is_array($_POST['categoryBox'])) { /* Clean categoryBox before use */ $_POST['categoryBox'] = array_map('intval', $_POST['categoryBox']); $filterValues = [ 'shop_list' => $shopList, ]; foreach ($_POST['categoryBox'] as $idCategoryLayered) { $filterValues['categories'][] = $idCategoryLayered; } foreach ($_POST as $key => $value) { if (!preg_match('~^(?P<key>layered_selection_.*)(?<!_filter_)(?<!type)(?<!show_limit)$~', $key, $matches)) { continue; } $filterValues[$matches['key']] = [ 'filter_type' => (int) Tools::getValue($matches['key'] . '_filter_type', 0), 'filter_show_limit' => (int) Tools::getValue($matches['key'] . '_filter_show_limit', 0), ]; } $values = [ 'name' => pSQL(Tools::getValue('layered_tpl_name')), 'filters' => pSQL(serialize($filterValues)), 'n_categories' => (int) count($filterValues['categories']), ]; if (!$idLayeredFilter) { $values['date_add'] = date('Y-m-d H:i:s'); $sql = 'INSERT INTO ' . _DB_PREFIX_ . 'layered_filter ' . '(name, filters, n_categories, date_add, id_layered_filter) ' . 'VALUES (' . '"' . pSQL($values['name']) . '", ' . '"' . $values['filters'] . '", ' . '' . (int) $values['n_categories'] . ', ' . '"' . pSQL($values['date_add']) . '", ' . '' . $idLayeredFilter . ')'; $this->getDatabase()->execute($sql); $idLayeredFilter = (int) $this->getDatabase()->Insert_ID(); } else { $this->getDatabase()->execute( 'DELETE FROM ' . _DB_PREFIX_ . 'layered_filter_shop WHERE `id_layered_filter` = ' . (int) $idLayeredFilter ); $sql = 'UPDATE ' . _DB_PREFIX_ . 'layered_filter ' . 'SET name = "' . pSQL($values['name']) . '", ' . 'filters = "' . $values['filters'] . '", ' . 'n_categories = ' . (int) $values['n_categories'] . ' ' . 'WHERE id_layered_filter = ' . $idLayeredFilter; $this->getDatabase()->execute($sql); } if (isset($assos)) { foreach ($assos as $asso) { $this->getDatabase()->execute( 'INSERT INTO ' . _DB_PREFIX_ . 'layered_filter_shop (`id_layered_filter`, `id_shop`) VALUES(' . $idLayeredFilter . ', ' . (int) $asso['id_shop'] . ')' ); } } $this->buildLayeredCategories(); $message = $this->displayConfirmation( $this->trans('Your filter', [], 'Modules.Facetedsearch.Admin') . ' "' . Tools::safeOutput(Tools::getValue('layered_tpl_name')) . '" ' . ( !empty($_POST['id_layered_filter']) ? $this->trans('was updated successfully.', [], 'Modules.Facetedsearch.Admin') : $this->trans('was added successfully.', [], 'Modules.Facetedsearch.Admin') ) ); } } } elseif (Tools::isSubmit('submitLayeredSettings')) { Configuration::updateValue('PS_LAYERED_CACHE_ENABLED', (int) Tools::getValue('ps_layered_cache_enabled')); Configuration::updateValue('PS_LAYERED_SHOW_QTIES', (int) Tools::getValue('ps_layered_show_qties')); Configuration::updateValue('PS_LAYERED_FULL_TREE', (int) Tools::getValue('ps_layered_full_tree')); Configuration::updateValue('PS_LAYERED_FILTER_PRICE_USETAX', (int) Tools::getValue('ps_layered_filter_price_usetax')); Configuration::updateValue('PS_LAYERED_FILTER_CATEGORY_DEPTH', (int) Tools::getValue('ps_layered_filter_category_depth')); Configuration::updateValue('PS_LAYERED_FILTER_PRICE_ROUNDING', (int) Tools::getValue('ps_layered_filter_price_rounding')); Configuration::updateValue('PS_LAYERED_FILTER_SHOW_OUT_OF_STOCK_LAST', (int) Tools::getValue('ps_layered_filter_show_out_of_stock_last')); Configuration::updateValue('PS_LAYERED_FILTER_BY_DEFAULT_CATEGORY', (int) Tools::getValue('ps_layered_filter_by_default_category')); $this->psLayeredFullTree = (int) Tools::getValue('ps_layered_full_tree'); $message = '<div class="alert alert-success">' . $this->trans('Settings saved successfully', [], 'Modules.Facetedsearch.Admin') . '</div>'; $this->invalidateLayeredFilterBlockCache(); } elseif (Tools::getValue('deleteFilterTemplate')) { $layered_values = $this->getDatabase()->getValue( 'SELECT filters FROM ' . _DB_PREFIX_ . 'layered_filter WHERE id_layered_filter = ' . (int) Tools::getValue('id_layered_filter') ); if ($layered_values) { $this->getDatabase()->execute( 'DELETE FROM ' . _DB_PREFIX_ . 'layered_filter WHERE id_layered_filter = ' . (int) Tools::getValue('id_layered_filter') . ' LIMIT 1' ); $this->buildLayeredCategories(); $message = $this->displayConfirmation($this->trans('Filter template deleted, categories updated (reverted to default Filter template).', [], 'Modules.Facetedsearch.Admin')); } else { $message = $this->displayError($this->trans('Filter template not found', [], 'Modules.Facetedsearch.Admin')); } } $categoryBox = []; $attributeGroups = $this->getDatabase()->executeS( 'SELECT ag.id_attribute_group, ag.is_color_group, agl.name, COUNT(DISTINCT(a.id_attribute)) n FROM ' . _DB_PREFIX_ . 'attribute_group ag 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' ); $features = $this->getDatabase()->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 fl.id_lang = ' . (int) $cookie->id_lang . ' GROUP BY fl.id_feature' ); if (Shop::isFeatureActive() && count(Shop::getShops(true, null, true)) > 1) { $helper = new HelperForm(); $helper->id = Tools::getValue('id_layered_filter', null); $helper->table = 'layered_filter'; $helper->identifier = 'id_layered_filter'; $this->context->smarty->assign('asso_shops', $helper->renderAssoShop()); } $treeCategoriesHelper = new HelperTreeCategories('categories-treeview'); $treeCategoriesHelper->setRootCategory((Shop::getContext() == Shop::CONTEXT_SHOP ? Category::getRootCategory()->id_category : 0)) ->setUseCheckBox(true); $moduleUrl = Tools::getProtocol(Tools::usingSecureMode()) . $_SERVER['HTTP_HOST'] . $this->getPathUri(); if (method_exists($this->context->controller, 'addJquery')) { $this->context->controller->addJS(_PS_JS_DIR_ . 'jquery/plugins/jquery.sortable.js'); } $this->context->controller->addJS($this->_path . 'views/dist/back.js'); $this->context->controller->addCSS($this->_path . 'views/dist/back.css'); if (Tools::getValue('add_new_filters_template')) { $this->context->smarty->assign([ 'current_url' => $this->context->link->getAdminLink('AdminModules') . '&configure=ps_facetedsearch&tab_module=front_office_features&module_name=ps_facetedsearch', 'uri' => $this->getPathUri(), 'id_layered_filter' => 0, 'template_name' => sprintf($this->trans('My template - %s', [], 'Modules.Facetedsearch.Admin'), date('Y-m-d')), 'attribute_groups' => $attributeGroups, 'features' => $features, 'total_filters' => 6 + count($attributeGroups) + count($features), ]); $this->context->smarty->assign('categories_tree', $treeCategoriesHelper->render()); return $this->display(__FILE__, 'views/templates/admin/add.tpl'); } if (Tools::getValue('edit_filters_template')) { $idLayeredFilter = (int) Tools::getValue('id_layered_filter'); $template = $this->getDatabase()->getRow( 'SELECT * FROM `' . _DB_PREFIX_ . 'layered_filter` WHERE id_layered_filter = ' . $idLayeredFilter ); if (!empty($template)) { $filters = Tools::unSerialize($template['filters']); $treeCategoriesHelper->setSelectedCategories($filters['categories']); $this->context->smarty->assign('categories_tree', $treeCategoriesHelper->render()); $selectShops = $filters['shop_list']; unset($filters['categories']); unset($filters['shop_list']); $this->context->smarty->assign([ 'current_url' => $this->context->link->getAdminLink('AdminModules') . '&configure=ps_facetedsearch&tab_module=front_office_features&module_name=ps_facetedsearch', 'uri' => $this->getPathUri(), 'id_layered_filter' => $idLayeredFilter, 'template_name' => $template['name'], 'attribute_groups' => $attributeGroups, 'features' => $features, 'filters' => $filters, 'total_filters' => 6 + count($attributeGroups) + count($features), 'default_filters' => $this->getDefaultFilters(), ]); return $this->display(__FILE__, 'views/templates/admin/view.tpl'); } } if(!isset($this->psLayeredFullTree)) { $this->psLayeredFullTree = (int) Configuration::get('PS_LAYERED_FULL_TREE');; } $this->context->smarty->assign([ 'message' => $message, 'uri' => $this->getPathUri(), 'PS_LAYERED_INDEXED' => (int) Configuration::getGlobalValue('PS_LAYERED_INDEXED'), 'current_url' => Tools::safeOutput(preg_replace('/&deleteFilterTemplate=[0-9]*&id_layered_filter=[0-9]*/', '', $_SERVER['REQUEST_URI'])), 'id_lang' => $this->getContext()->cookie->id_lang, 'token' => substr(Tools::hash('ps_facetedsearch/index'), 0, 10), 'base_folder' => urlencode(_PS_ADMIN_DIR_), 'price_indexer_url' => $moduleUrl . 'ps_facetedsearch-price-indexer.php' . '?token=' . substr(Tools::hash('ps_facetedsearch/index'), 0, 10), 'full_price_indexer_url' => $moduleUrl . 'ps_facetedsearch-price-indexer.php' . '?token=' . substr(Tools::hash('ps_facetedsearch/index'), 0, 10) . '&full=1', 'attribute_indexer_url' => $moduleUrl . 'ps_facetedsearch-attribute-indexer.php' . '?token=' . substr(Tools::hash('ps_facetedsearch/index'), 0, 10), 'clear_cache_url' => $moduleUrl . 'ps_facetedsearch-clear-cache.php' . '?token=' . substr(Tools::hash('ps_facetedsearch/index'), 0, 10), 'filters_templates' => $this->getDatabase()->executeS('SELECT * FROM ' . _DB_PREFIX_ . 'layered_filter ORDER BY date_add DESC'), 'show_quantities' => Configuration::get('PS_LAYERED_SHOW_QTIES'), 'cache_enabled' => Configuration::get('PS_LAYERED_CACHE_ENABLED'), 'full_tree' => $this->psLayeredFullTree, 'category_depth' => Configuration::get('PS_LAYERED_FILTER_CATEGORY_DEPTH'), 'price_use_tax' => (bool) Configuration::get('PS_LAYERED_FILTER_PRICE_USETAX'), 'limit_warning' => $this->displayLimitPostWarning(21 + count($attributeGroups) * 3 + count($features) * 3), 'price_use_rounding' => (bool) Configuration::get('PS_LAYERED_FILTER_PRICE_ROUNDING'), 'show_out_of_stock_last' => (bool) Configuration::get('PS_LAYERED_FILTER_SHOW_OUT_OF_STOCK_LAST'), 'filter_by_default_category' => (bool) Configuration::get('PS_LAYERED_FILTER_BY_DEFAULT_CATEGORY'), ]); return $this->display(__FILE__, 'views/templates/admin/manage.tpl'); } } the only modification made in the new field is the replacement of the request: $features = $this->getDatabase()->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' ); By: $features = $this->getDatabase()->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 fl.id_lang = ' . (int) $cookie->id_lang . ' GROUP BY fl.id_feature' ); All features are now accessible from the faceted module backoffice 😉 Edit : Attention ! All custom values will be displayed, even if several custom values are identical, they will all be displayed. Edited September 8, 2022 by GaetanV (see edit history) Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now