Custom Product Listing Page Filters Not Working – Magento

attributescollection;product-attributeproduct-list

I have inherited a Magento job, in which they have a custom view for "brands". This basically filters the products based on a specific brand "code". However, the main problem is that this list of products isn't "filterable" by the left-hand navigation, which is what I've been tasked with doing. I'm putting as much information as I can below, in the hopes someone can see something that I've missed.

Any help here would be extremely appreciated.

The layout setup is currently as follows:

<brands_index_name>
    <remove name="catalog.shopby" />
    <!--<remove name="catalog.leftnav" />-->
    <reference name="left">
        <block type="brands/catalog_layer_brands" name="brands.leftnav" template="brands/layer/view.phtml">
            <action method="unsetChild"><alias>brand</alias></action>
        </block>
    </reference>
    <reference name="content">          
        <block type="catalog/product_list" name="product_list" template="brands/list.phtml">
            <!-- Add toolbar to product list -->
    <block type="catalog/product_list_toolbar" name="product_list_toolbar" template="catalog/product/list/toolbar.phtml">
        <!-- Add pager to toolbar -->
        <block type="page/html_pager" name="product_list_toolbar_pager"/>
    </block>

    <!-- Specify toolbar block name -->
    <action method="setToolbarBlockName">
        <name>product_list_toolbar</name>
    </action>

            <!-- Use custom product collection -->
    <action method="setCollection">
        <value helper="brands/getProductCollection" />
    </action>

    <!-- Use custom available sort by orders -->
    <action method="setAvailableOrders">
        <value helper="brands/getAvailableOrders" />
    </action>

    <!-- Set the default sort by order -->
    <action method="setSortBy">
        <value>price</value>
    </action>

    <!-- Set default direction to ascending -->
    <action method="setDefaultDirection">
        <value>asc</value>
    </action>

    <action method="setColumnCount">
        <coulumn>5</coulumn>
    </action>
        </block>
    </reference>

</brands_index_name>

So the products are retrieved for the main page with "brands/getProductCollection"

class Tos_Brands_Helper_Data extends Mage_Core_Helper_Abstract
{
/**
 * Array of available orders to be used for sort by
 *
 * @return array
 */
public function getAvailableOrders()
{
    return array(
        // attribute name => label to be used
        'price' => $this->__('Price')
    );
}

/**
 * Return product collection to be displayed by our list block
 *
 * @return Mage_Catalog_Model_Resource_Product_Collection
 */
public function getProductCollection()
{
    $rootCategoryId = Mage::app()->getStore()->getRootCategoryId();
    $category = Mage::getModel('catalog/category')->load($rootCategoryId);

    $brand_id = Mage::app()->getRequest()->getParam('brand-id');
    $brands = Mage::getModel('brands/brands')->getCollection();
    $brands->addFieldToFilter('entity_id', $brand_id);
    $brand = $brands->getData();

    $collection = $category->getProductCollection()
      ->addAttributeToSelect(Mage::getSingleton('catalog/config')->getProductAttributes())
      ->addAttributeToSelect('supplier_code')->addAttributeToFilter('supplier_code', array('eq' => $brand[0]['brand_code']))
      ->addMinimalPrice()
      ->addFinalPrice()
      ->addTaxPercents()
      ->addStoreFilter()
      ->addUrlRewrite($rootCategoryId);

    Mage::getSingleton('catalog/product_status')->addVisibleFilterToCollection($collection);
    Mage::getSingleton('catalog/product_visibility')->addVisibleInCatalogFilterToCollection($collection);

    return $collection;
}
}

The filter on the side also needs to be adjusted to take into account we only want filters relating to the brand itself:

class Tos_Brands_Model_Catalog_Layer extends Mage_Catalog_Model_Layer
{

public function getProductCollection()
{
    $rootCategoryId = Mage::app()->getStore()->getRootCategoryId();
    $rootCategory = Mage::getModel('catalog/category')->load($rootCategoryId);
    $collection = $rootCategory->getProductCollection();
    $this->prepareProductCollection($collection);
    $this->_productCollections[$rootCategoryId] = $collection;
    return $collection;
}

public function prepareProductCollection($collection)
{
    $brand_id = Mage::app()->getRequest()->getParam('brand-id');
    $brands = Mage::getModel('brands/brands')->getCollection();
    $brands->addFieldToFilter('entity_id', $brand_id);
    $brand = $brands->getData();

    parent::prepareProductCollection($collection);
    $collection->addAttributeToSelect('supplier_code')
        ->addAttributeToFilter('supplier_code', array('eq' => $brand[0]['brand_code']));

    return $this;
}

}

If I select a price or something to filter within the left hand nav, the nav correctly identifies that it is filtering by something, however it doesn't return the correct number of results – and the main product results on the page are unaffected.

I've tried to implement something along the lines of

$layer = Mage::getModel("catalog/layer");
$filterable = $layer->getFilterableAttributes();
foreach ($filterable as $attribute) {
    if (isset($_GET[$attribute->getAttributeCode()])) {
       $collection->addAttributeToSelect(...)->addAttributeToFilter(...);
    }
}

To try and manually pass through any filters, however this doesn't work due to the fact that "price" filters come through as "100 – 200" or similar, as as such need specific formatting. I could put in a check for prices and format accordingly, but with other attributes potentially being used it could cause some problems.

I'm at a complete loss here as to how to apply the filters to the searches, and I can't find anything online to suggest where and how to ensure that they are applied to the search.

Again, any help would be amazing, I've been pulling my hair out over this for the past 4 hours or so (it took long enough to reformat it all so I could get the filters displaying in the first place!).

Best Answer

My suggestion is to look into the Mage_Catalog_Block_Product_List class. I think the problem with the filters not being applied is caused by how you initialize the product collection in the brand helper getProductCollection function.

Maybe you could try doing something like this in your helper:

public function getLayer()
{
    $layer = Mage::registry('current_layer');
    if ($layer) {
        return $layer;
    }
    return Mage::getSingleton('catalog/layer');
}

public function getProductCollection()
{
    $layer = $this->getLayer();

    $brandId = Mage::app()->getRequest()->getParam('brand-id');
    $brand = Mage::getModel('brands/brands')->load($brandId);

    $collection = $layer->getProductCollection()
        ->addAttributeToFilter('supplier_code', $brand->getBrandCode());

    return $collection;
}
Related Topic