Nick Parsons
Nick Parsons

Reputation: 8607

Layered navigation with custom attribute

We have a layered navigation (screenshot) that allows our users to filter by category, price, and colors. category and price work just fine, as they are default to Magento. The issue comes when attempting to filter by color, a custom attribute.

It throws an exception. I was able to track down the stack trace, but I'm unable to make sense of it. Wondering if anyone can help point me in the right direction. Trace: https://gist.github.com/4490917

We're using Magento Enterprise v1.12.0.2

Upvotes: 0

Views: 4544

Answers (2)

Shannon Deedler
Shannon Deedler

Reputation: 1

You could simply remove the enterprisesearch block from the layout for example catalogsearch.xml below:

    <catalogsearch_result_index translate="label">
    ...
        <reference name="left">
            <remove name="enterprisesearch.leftnav"/>
        </reference>
        <reference name="right">
            <block type="catalogsearch/layer" name="catalogsearch.rightnav" before="-" template="catalog/layer/view.phtml"/>
        </reference>
    ...
    </catalogsearch_result_index>

The error is occurring because their are two block doing the same thing in the layout. The enterprise search is there by default.

Upvotes: 0

Nick Parsons
Nick Parsons

Reputation: 8607

There's an issue with app/Mage/Catalog/Model/Resource/Layer/Filter/Attribute.php

Swap out your class with the following and it problem should be solved.

class Mage_Catalog_Model_Resource_Layer_Filter_Attribute extends Mage_Core_Model_Resource_Db_Abstract
{
/**
 * Initialize connection and define main table name
 *
 */
protected function _construct()
{
    $this->_init('catalog/product_index_eav', 'entity_id');
}

/**
 * Apply attribute filter to product collection
 *
 * @param Mage_Catalog_Model_Layer_Filter_Attribute $filter
 * @param int $value
 * @return Mage_Catalog_Model_Resource_Layer_Filter_Attribute
 */
public function applyFilterToCollection($filter, $value)
{

    $filterSingleton = FilterSingleton::singleton();

    if (!isset($filterSingleton->return)) {

        $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()),
            join(' AND ', $conditions),
            array()
        );

        $filterSingleton->return = $this;

        return $this;

    } else {
        return $filterSingleton->return;
    }
}

/**
 * Retrieve array with products counts per attribute option
 *
 * @param Mage_Catalog_Model_Layer_Filter_Attribute $filter
 * @return array
 */
public function getCount($filter)
{
    // clone select from collection with filters
    $select = clone $filter->getLayer()->getProductCollection()->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);

    $connection = $this->_getReadAdapter();
    $attribute  = $filter->getAttributeModel();
    $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 = ?", $filter->getStoreId()),
    );

    $select
        ->join(
            array($tableAlias => $this->getMainTable()),
            join(' AND ', $conditions),
            array('value', 'count' => new Zend_Db_Expr("COUNT({$tableAlias}.entity_id)")))
        ->group("{$tableAlias}.value");

    return $connection->fetchPairs($select);
    }
}
class FilterSingleton {

static private $instance;

public $return = null;

    private function __construct() {

}

static public function singleton() {
     if (!isset(self::$instance)) {
        $c = __CLASS__;
        self::$instance = new $c;
    }

    return self::$instance;
}
}

http://aceph.tumblr.com/post/21851233473/magento-you-cannot-define-a-correlation-name

Upvotes: 2

Related Questions