What I did in this case was to rewrite both the model and the corresponding resource, so first rewrite the class Mage_Catalog_Model_Layer_Filter_Attribute
to be able to accept multiple values. In my case, I am using commas as a separator, so I can filter like ?my_attribute=1,2,3
In the method apply()
I parse the attribute to put the different values in an array:
public function apply(Zend_Controller_Request_Abstract $request, $filterBlock)
{
$filter = $request->getParam($this->_requestVar);
if (is_array($filter)) {
return $this;
}
// MP customized
$filter = explode(',', $filter);
if (count($filter) < 1) {
return $this;
} else if ($filter == '') {
return $this;
}
if (count($filter) == 1) {
$filter = $filter[0];
}
if ($filter == '') {
return $this;
}
if ($filter) {
$this->_initItems();
$this->_getResource()->applyFilterToCollection($this, $filter);
$text = '';
foreach ($filter as $att) {
($text == '') ? $text = $this->_getOptionText($att) : $text .= ', '.$this->_getOptionText($att);
}
if (count($filter) == 1) {
$text = $this->_getOptionText($filter);
}
$this->getLayer()->getState()->addFilter($this->_createItem($text, $filter));
}
// End MP customized
return $this;
}
Then in the file Mage_Catalog_Model_Resource_Eav_Mysql4_Layer_Filter_Attribute
you have to make sure that you are able to filter for multiple values in your query, so I rewrote the following method like this:
public function applyFilterToCollection($filter, $value)
{
$collection = $filter->getLayer()->getProductCollection();
$attribute = $filter->getAttributeModel();
$connection = $this->_getReadAdapter();
$tableAlias = $attribute->getAttributeCode() . '_idx';
$conditions = array(
"{$tableAlias}.entity_id = e.entity_id",
$connection->quoteInto("{$tableAlias}.attribute_id = ?", $attribute->getAttributeId()),
$connection->quoteInto("{$tableAlias}.store_id = ?", $collection->getStoreId()),
$connection->quoteInto("{$tableAlias}.value IN (?)", $value)
); // Added IN (?) notation for arrays
$collection->getSelect()->join(
array($tableAlias => $this->getMainTable()),
join(' AND ', $conditions),
array()
// MP Need distinct here to avoid getting the same config product from
// different basic products when filtering for different values
// in the same attribute
)->distinct(true);
return $this;
}
Okay, so I'm actually getting somewhere by building a completely different collection...
$category_id = 3;
$collection = Mage::getModel('catalog/category')->load($category_id)
->getProductCollection()
->addAttributeToSelect('*') // add all attributes - optional
->addAttributeToFilter('type_id', array('eq' => 'configurable'))
->addAttributeToFilter('visibility', array('in' => array(Mage_Catalog_Model_Product_Visibility::VISIBILITY_BOTH, Mage_Catalog_Model_Product_Visibility::VISIBILITY_IN_SEARCH, Mage_Catalog_Model_Product_Visibility::VISIBILITY_IN_CATALOG)))
->addAttributeToFilter('status', array('eq' => Mage_Catalog_Model_Product_Status::STATUS_ENABLED))
->addStoreFilter($storeId);
And then fetch the category ID's from the loaded products:-
$cats = $product->getCategoryIds();
And loop through (as @paj suggested in the comments) to get the category data for each:-
foreach ($cats as $category_id) {
$category = Mage::getModel('catalog/category')->setStoreId(Mage::app()->getStore()->getId())->load($category_id);
}
I'm then able to get what I want for each product like:-
$category->getId()
$category->getName()
Meaning my required mapping works well:-
if ($category->getId()==10) {
$cmap = 'Clothing > Trousers';
}
Best Answer
You can sort it by give values
Check for detail