Add previewFilterGroupProducts AJAX handler
- Add case in handleEntitySelectorAjax switch for previewFilterGroupProducts - Implement ajaxPreviewFilterGroupProducts() to get products by attribute/feature group - Returns items with name, reference, manufacturer, image for popover preview Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -263,6 +263,9 @@ trait EntitySelector
|
|||||||
case 'getCategoryTree':
|
case 'getCategoryTree':
|
||||||
$this->ajaxGetCategoryTree();
|
$this->ajaxGetCategoryTree();
|
||||||
return true;
|
return true;
|
||||||
|
case 'previewFilterGroupProducts':
|
||||||
|
$this->ajaxPreviewFilterGroupProducts();
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
@@ -583,6 +586,109 @@ trait EntitySelector
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* AJAX: Preview products that have any value from a specific attribute or feature group
|
||||||
|
* Used by filter panel toggle buttons
|
||||||
|
*/
|
||||||
|
protected function ajaxPreviewFilterGroupProducts()
|
||||||
|
{
|
||||||
|
$groupId = (int) Tools::getValue('group_id');
|
||||||
|
$groupType = Tools::getValue('group_type'); // 'attribute' or 'feature'
|
||||||
|
$limit = (int) Tools::getValue('limit', 10);
|
||||||
|
|
||||||
|
if (!$groupId || !in_array($groupType, ['attribute', 'feature'])) {
|
||||||
|
die(json_encode([
|
||||||
|
'success' => false,
|
||||||
|
'error' => 'Invalid parameters'
|
||||||
|
]));
|
||||||
|
}
|
||||||
|
|
||||||
|
$idLang = (int) Context::getContext()->language->id;
|
||||||
|
$idShop = (int) Context::getContext()->shop->id;
|
||||||
|
|
||||||
|
try {
|
||||||
|
$db = Db::getInstance();
|
||||||
|
|
||||||
|
if ($groupType === 'attribute') {
|
||||||
|
// Get products with any attribute from this group
|
||||||
|
$sql = new DbQuery();
|
||||||
|
$sql->select('DISTINCT p.id_product');
|
||||||
|
$sql->from('product', 'p');
|
||||||
|
$sql->innerJoin('product_shop', 'ps', 'ps.id_product = p.id_product AND ps.id_shop = ' . $idShop);
|
||||||
|
$sql->innerJoin('product_attribute', 'pa', 'pa.id_product = p.id_product');
|
||||||
|
$sql->innerJoin('product_attribute_combination', 'pac', 'pac.id_product_attribute = pa.id_product_attribute');
|
||||||
|
$sql->innerJoin('attribute', 'a', 'a.id_attribute = pac.id_attribute AND a.id_attribute_group = ' . $groupId);
|
||||||
|
$sql->where('ps.active = 1');
|
||||||
|
} else {
|
||||||
|
// Get products with any feature value from this group
|
||||||
|
$sql = new DbQuery();
|
||||||
|
$sql->select('DISTINCT p.id_product');
|
||||||
|
$sql->from('product', 'p');
|
||||||
|
$sql->innerJoin('product_shop', 'ps', 'ps.id_product = p.id_product AND ps.id_shop = ' . $idShop);
|
||||||
|
$sql->innerJoin('feature_product', 'fp', 'fp.id_product = p.id_product');
|
||||||
|
$sql->innerJoin('feature_value', 'fv', 'fv.id_feature_value = fp.id_feature_value AND fv.id_feature = ' . $groupId);
|
||||||
|
$sql->where('ps.active = 1');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get total count first
|
||||||
|
$countSql = clone $sql;
|
||||||
|
$countResult = $db->executeS($countSql);
|
||||||
|
$totalCount = count($countResult);
|
||||||
|
|
||||||
|
// Get limited results for preview
|
||||||
|
$sql->limit($limit);
|
||||||
|
$results = $db->executeS($sql);
|
||||||
|
$productIds = array_column($results, 'id_product');
|
||||||
|
|
||||||
|
// Get product details for preview
|
||||||
|
$items = [];
|
||||||
|
if (!empty($productIds)) {
|
||||||
|
$productSql = new DbQuery();
|
||||||
|
$productSql->select('p.id_product, pl.name, p.reference, i.id_image, m.name as manufacturer');
|
||||||
|
$productSql->from('product', 'p');
|
||||||
|
$productSql->innerJoin('product_lang', 'pl', 'pl.id_product = p.id_product AND pl.id_lang = ' . $idLang . ' AND pl.id_shop = ' . $idShop);
|
||||||
|
$productSql->leftJoin('image', 'i', 'i.id_product = p.id_product AND i.cover = 1');
|
||||||
|
$productSql->leftJoin('manufacturer', 'm', 'm.id_manufacturer = p.id_manufacturer');
|
||||||
|
$productSql->where('p.id_product IN (' . implode(',', array_map('intval', $productIds)) . ')');
|
||||||
|
$productSql->limit($limit);
|
||||||
|
|
||||||
|
$products = $db->executeS($productSql);
|
||||||
|
|
||||||
|
foreach ($products as $product) {
|
||||||
|
$imageUrl = null;
|
||||||
|
if ($product['id_image']) {
|
||||||
|
$imageUrl = Context::getContext()->link->getImageLink(
|
||||||
|
Tools::link_rewrite($product['name']),
|
||||||
|
$product['id_product'] . '-' . $product['id_image'],
|
||||||
|
'small_default'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
$items[] = [
|
||||||
|
'id' => (int) $product['id_product'],
|
||||||
|
'name' => $product['name'],
|
||||||
|
'reference' => $product['reference'],
|
||||||
|
'manufacturer' => $product['manufacturer'],
|
||||||
|
'image' => $imageUrl
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
die(json_encode([
|
||||||
|
'success' => true,
|
||||||
|
'items' => $items,
|
||||||
|
'count' => $totalCount,
|
||||||
|
'hasMore' => $totalCount > count($items)
|
||||||
|
]));
|
||||||
|
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
die(json_encode([
|
||||||
|
'success' => false,
|
||||||
|
'error' => $e->getMessage()
|
||||||
|
]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Apply modifiers (sort, limit) to product IDs
|
* Apply modifiers (sort, limit) to product IDs
|
||||||
* Delegates to ProductConditionResolver
|
* Delegates to ProductConditionResolver
|
||||||
|
|||||||
Reference in New Issue
Block a user