On 12/11/2020 at 2:09 AM, vpoupet said:Just in case anyone is still looking for a solution for PS 1.7, here's a solution based on Binded's solution.
In the file modules/ps_facetedsearch/src/Filters/Products.php, right after the line
$matchingProductList = $this->searchAdapter->execute();add the block
if (isset($selectedFilters['id_attribute_group']) && $selectedFilters['id_attribute_group']) { $this->setProductAttributeId($selectedFilters, $matchingProductList); }
Then at the end of the class, add the two following methods :
private function setProductAttributeId($selected_filters, &$products) { foreach ($products as &$product) { $attribute_id_sets = []; foreach($selected_filters['id_attribute_group'] as $attribute_group) { $attribute_id_sets[] = $this->getProductAttributeIds($product['id_product'], $attribute_group); } if (!empty($attribute_id_sets)) { $attribute_ids = array_pop($attribute_id_sets); while (!empty($attribute_id_sets)) { $attribute_ids = array_intersect($attribute_ids, array_pop($attribute_id_sets)); } } if (!empty($attribute_ids)) { $product['id_product_attribute'] = array_pop($attribute_ids); } } } private function getProductAttributeIds($id_product, $attribute_group) { $attribute_ids = []; foreach ($attribute_group as $key => $id_attribute) { $query = new DbQuery(); $query->select('ps_product_attribute.id_product_attribute'); $query->from('product_attribute_combination'); $query->innerJoin('product_attribute', null, 'ps_product_attribute.id_product_attribute = ps_product_attribute_combination.id_product_attribute'); $query->where('ps_product_attribute.id_product = \'' . $id_product . '\' AND ps_product_attribute_combination.id_attribute = \'' . $id_attribute . '\''); $results = Db::getInstance()->executeS($query); foreach ($results as $result) { $attribute_ids[] = $result['id_product_attribute']; } } return $attribute_ids; }
What this does is that whenever some filters are selected in the faceted search module, it looks for the first variation of each product that matches all filters (matches one of the conditions in each block) and displays the default image for this variation.
Note : My PHP skills are extremely low, so it's very likely that the code in the two added functions can be rewritten in a much more elegant way.
Perfect! Works like a charm. If anyone can't make it work then just need to modify a couple of things. Require to use DbQuery and Db class. To insert them just go to the top of the file and insert below lines after 'use Configuration;'
Find below
use Configuration;
Add below after
use DbQuery;
use Db;
The above modification should work for anyone. If it doesn't then you will have to look at the below modification.
Modify the getProductAttributeIds($id_product, $attribute_group) class if required. You will notice that 'ps_' before 'product_attribute' and some other column names. That 'ps_' is the prefix of your database table columns. If you had set something different then you will have to replace that 'ps_' with your own. If you are not sure then look at the database tables and any columns to find out your prefix. By default it's 'ps_' unless you have opted out during installation and left it blank.
The complete function will look like below (without any database prefix like 'ps_').
private function getProductAttributeIds($id_product, $attribute_group){
$attribute_ids = [];
foreach ($attribute_group as $key => $id_attribute) {
$query = new DbQuery();
$query->select('product_attribute.id_product_attribute');
$query->from('product_attribute_combination');
$query->innerJoin('product_attribute', null, 'product_attribute.id_product_attribute = product_attribute_combination.id_product_attribute');
$query->where('product_attribute.id_product = \'' . $id_product . '\' AND product_attribute_combination.id_attribute = \'' . $id_attribute . '\'');
$results = Db::getInstance()->executeS($query);
foreach ($results as $result) {
$attribute_ids[] = $result['id_product_attribute'];
}
}
return $attribute_ids;
}