0

My scenario is as follows. I have the following attributes which are available in layered navigation.

Color (have 5 products)
Size( have 10 products)
Shape(have 3 products)

If I filter by Color and Size it'll show the intersection of those 15 products as the result. So the resultant number of products is less than 15. But my requirement is to show all the 15 products. Following are few more examples which will demonstrate what I actually want to do.

e.g. Filter by Size and Shape should result with 13 products

Any suggestions on this will be highly appreciated. If there's any extensions available please mention as well.

  • have you got any solution or any reference link? – Magento Learner Mar 30 '16 at 12:09
1

Layered Navigation filters are applied in Mage_Catalog_Block_Layer_View::_prepareLayout() inside the last init() call.

     foreach ($filterableAttributes as $attribute) {
        if ($attribute->getAttributeCode() == 'price') {
            $filterBlockName = $this->_priceFilterBlockName;
        } elseif ($attribute->getBackendType() == 'decimal') {
            $filterBlockName = $this->_decimalFilterBlockName;
        } else {
            $filterBlockName = $this->_attributeFilterBlockName;
        }

        $this->setChild($attribute->getAttributeCode() . '_filter',
            $this->getLayout()->createBlock($filterBlockName)
                ->setLayer($this->getLayer())
                ->setAttributeModel($attribute)
                ->init());
    }

To union all the results first of all change Mage_Catalog_Model_Resource_Layer_Filter_Attribute::applyFilterToCollection() which is called from block's init():

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 = ?", $value)
    );

    $collection->getSelect()->join(
        array($tableAlias => $this->getMainTable()),
        implode(' AND ', $conditions),
        array()
    );

    return $this;
}

Here remove $connection->quoteInto("{$tableAlias}.value = ?", $value) from conditions and instead put this Mysql clause into filter model using

$filter->setData('condition', $connection->quoteInto("{$tableAlias}.value = ?", $value));

Then back in Mage_Catalog_Block_Layer_View::_prepareLayout() add one more loops which would collect all filter conditions and join them using logical OR and add the whole expression into SELECT's WHERE clause.

  • will you explain in somewhat more detail? – Magento Learner Mar 30 '16 at 12:03
0

You need to modify logic of the app\code\core\Mage\Catalog\Model\Resource\Layer\Filter\Attribute.php class.

Currently, for each new attribute this class gets the current products select object and joins the index table based on the attribute value.

$collection->getSelect()->join(
        array($tableAlias => $this->getMainTable()),
        implode(' AND ', $conditions),
        array()
    ); 

Each join narrows the products selection. Your task is to adjust the algorithm to merge or union products instead.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.