让我们说,这些是颜色和大小的属性。颜色有以下选项红色,绿色和蓝色,尺寸有以下选项小,中,大。现在,假设产品系列中有两种产品,一种产品是红色,尺寸小,另一种是绿色,大小适中。所以,我想要输出如下
我不想先获取属性列表集合,然后迭代并匹配集合中每个产品的属性,因为这将非常慢并且消耗内存。
答案 0 :(得分:0)
我调试了分层导航在Magento中的工作方式,并基于我提出的下述解决方案。
try{
//Get product collection and apply filter to it if any. Here I am applying dummy color filter
$prodCollection = Mage::getModel('catalog/product')->getCollection()
->addAttributeToFilter('color',array('in' => array(3,4))); //change this filter ad per your need
$prodCollection
->addAttributeToSelect(Mage::getSingleton('catalog/config')->getProductAttributes())
->addMinimalPrice()
->addFinalPrice()
->addTaxPercents()
->addUrlRewrite(Mage::getModel('catalog/layer')->getCurrentCategory()->getId());
Mage::getSingleton('catalog/product_status')->addVisibleFilterToCollection($prodCollection);
Mage::getSingleton('catalog/product_visibility')->addVisibleInCatalogFilterToCollection($prodCollection);
$setId = 4; //default attribute set id. change this as pre your need. You can also make this an array
//Get catalog attribute collection of some attribute sets.
$attrCollection = Mage::getResourceModel('catalog/product_attribute_collection');
$attrCollection
->setItemObjectClass('catalog/resource_eav_attribute')
->setAttributeSetFilter($setId)
->addStoreLabel(Mage::app()->getStore()->getId())
->setOrder('position', 'ASC');
$attrCollection->addIsFilterableFilter(); //Check if attributes are filterable or not
$attrCollection->load();
$connection = Mage::getSingleton('core/resource')->getConnection('core_read');
$filterResourceModel = Mage::getResourceModel('catalog/layer_filter_attribute');
//Apply filter to product collection, if any
if(1){ //Check if any filters are applied on product collection from query string (?color=4&size=8)
foreach($attrCollection as $attribute){
//For now just for testing purpose, I have hardcoded it to work only for single attribute i.e. color
if($attribute->getAttributeCode() != 'color'){
continue;
}
//I am assuming color filter is applied twice
$filterName = 'color';
$filterId = 92;
$filterVal = array(3,4);
$tableAlias = $attribute->getAttributeCode() . '_fa';
$conditions = array(
"{$tableAlias}.entity_id = e.entity_id",
$connection->quoteInto("{$tableAlias}.attribute_id = ?", $attribute->getAttributeId()),
$connection->quoteInto("{$tableAlias}.store_id = ?", $prodCollection->getStoreId()),
$connection->quoteInto("{$tableAlias}.value IN (?)", $filterVal)
);
$prodCollection->getSelect()->join(
array($tableAlias => $filterResourceModel->getMainTable()),
implode(' AND ', $conditions),
array()
);
}
}
//Iterate each attribute one by one. For now just for testing purpose, I have hardcoded it to work only for single attribute i.e. color
foreach($attrCollection as $attribute){
if($attribute->getAttributeCode() != 'color'){
continue;
}
//find attributes options
$options = $attribute->getFrontend()->getSelectOptions();
// clone select from collection with filters
$select = clone $prodCollection->getSelect();
// reset columns, order and limitation conditions
$select->reset(Zend_Db_Select::COLUMNS);
$select->reset(Zend_Db_Select::ORDER);
$select->reset(Zend_Db_Select::LIMIT_COUNT);
$select->reset(Zend_Db_Select::LIMIT_OFFSET);
$tableAlias = sprintf('%s_idx', $attribute->getAttributeCode());
$conditions = array(
"{$tableAlias}.entity_id = e.entity_id",
$connection->quoteInto("{$tableAlias}.attribute_id = ?", $attribute->getAttributeId()),
$connection->quoteInto("{$tableAlias}.store_id = ?", Mage::app()->getStore()->getId()), //$filter->getStoreId()
);
$select
->join(
array($tableAlias => $filterResourceModel->getMainTable()),
join(' AND ', $conditions),
array('value', 'count' => new Zend_Db_Expr("COUNT({$tableAlias}.entity_id)")))
->group("{$tableAlias}.value");
$optionsCount = $connection->fetchPairs($select);
$data = array();
foreach ($options as $option) {
if (is_array($option['value'])) {
continue;
}
if (Mage::helper('core/string')->strlen($option['value'])) {
$data[] = array(
'label' => $option['label'],
'value' => $option['value'],
'count' => isset($optionsCount[$option['value']]) ? $optionsCount[$option['value']] : 0,
);
}
}
echo '<pre>'; print_r($data); die('<><>');
}
}catch(Exception $e){
}