Magento 1.8 Collection Filtering – Filter on Product Listing Using addAttributeToFilter

collection-filteringmagento-1.8

I've been asked to help upgrading a Magento shop from version 1.5.1 to Magento 1.8.1
I'm not a Magento developer, but have much experience with PHP.

The previous developer added a way to filter products based on a custom attributes, width. There are 2 two input fields, width-from and width-to, and when the user input something in them and presses enter, it reloads the product listing page and adds them as GET paramters (http://site.com../?width_from=...).

Since there is no documentation of the solution, I've tried looking around to see where it is implemented. As far as I can tell, modifications have been made to app/code/local/Mage/Catalog/Model/Layer.php, where the function getProductCollection()have been altered:

public function getProductCollection()
{
    if (isset($this->_productCollections[$this->getCurrentCategory()->getId()])) {
            $collection = $this->_productCollections[$this->getCurrentCategory()->getId()];
    } else {
        $collection = $this->getCurrentCategory()->getProductCollection();
        $this->prepareProductCollection($collection);
            $this->_productCollections[$this->getCurrentCategory()->getId()] = $collection;
    }
        if(!empty($_GET['width-from'])) {
            $collection->addAttributeToFilter('width', array('gteq' => (int) $_GET['width-from']));
        }
        if(!empty($_GET['width-to'])) {
            $collection->addAttributeToFilter('width', array('lteq' => (int) $_GET['width-to']));
        }

            //$collection->printlogquery(true);

    return $collection;
}

So, as you can see the previous developer used addAttributetoFilter to add the filter. However, I'm having problems moving this code to Magento 1.8.1. I've tried to add the following to getProductCollection in app/code/core/Mage/Catalog/Model/Layer.php:

public function getProductCollection()
{
    if (isset($this->_productCollections[$this->getCurrentCategory()->getId()])) {
        $collection = $this->_productCollections[$this->getCurrentCategory()->getId()];
    } else {
        $collection = $this->getCurrentCategory()->getProductCollection();
        $this->prepareProductCollection($collection);
        $this->_productCollections[$this->getCurrentCategory()->getId()] = $collection;
    }

    $collection->clear();

        if(!empty($_GET['width-from'])) {
            $collection->addAttributeToFilter('width', array('gteq' => (int) $_GET['width-from']));
        }
        if(!empty($_GET['width-to'])) {
            $collection->addAttributeToFilter('width', array('lteq' => (int) $_GET['width-to']));
        }

    $collection->load();    

           // $collection->printlogquery(true);

    return $collection;
}

Basically, I've added the calls to addAtributetoFilter, as well as called the clear()and load() method (just to check, doesn't seem to make a difference). However, when I input something in the filters it causes the following error:

SQLSTATE[42S22]: Column not found: 1054 Unknown column 'e.width' in 'where clause'

Trace:
#0 /var/www/shop-reza.dk/public_html/lib/Varien/Db/Statement/Pdo/Mysql.php(110): Zend_Db_Statement_Pdo->_execute(Array)
#1 /var/www/shop-reza.dk/public_html/app/code/core/Zend/Db/Statement.php(291): Varien_Db_Statement_Pdo_Mysql->_execute(Array)
#2 /var/www/shop-reza.dk/public_html/lib/Zend/Db/Adapter/Abstract.php(479): Zend_Db_Statement->execute(Array)
#3 /var/www/shop-reza.dk/public_html/lib/Zend/Db/Adapter/Pdo/Abstract.php(238): Zend_Db_Adapter_Abstract->query('SELECT FLOOR((R...', Array)
#4 /var/www/shop-reza.dk/public_html/lib/Varien/Db/Adapter/Pdo/Mysql.php(428): Zend_Db_Adapter_Pdo_Abstract->query('SELECT FLOOR((R...', Array)
#5 /var/www/shop-reza.dk/public_html/lib/Zend/Db/Adapter/Abstract.php(808): Varien_Db_Adapter_Pdo_Mysql->query(Object(Varien_Db_Select), Array)
#6 /var/www/shop-reza.dk/public_html/app/code/core/Mage/Catalog/Model/Resource/Layer/Filter/Price.php(274): Zend_Db_Adapter_Abstract->fetchPairs(Object(Varien_Db_Select))
#7 /var/www/shop-reza.dk/public_html/app/code/core/Mage/Catalog/Model/Layer/Filter/Price.php(158): Mage_Catalog_Model_Resource_Layer_Filter_Price->getCount(Object(Mage_Catalog_Model_Layer_Filter_Price), 1000)
#8 /var/www/shop-reza.dk/public_html/app/code/core/Mage/Catalog/Model/Layer/Filter/Price.php(115): Mage_Catalog_Model_Layer_Filter_Price->getRangeItemCounts(1000)
#9 /var/www/shop-reza.dk/public_html/app/code/core/Mage/Catalog/Model/Layer/Filter/Price.php(314): Mage_Catalog_Model_Layer_Filter_Price->getPriceRange()
#10 /var/www/shop-reza.dk/public_html/app/code/core/Mage/Catalog/Model/Layer/Filter/Abstract.php(151): Mage_Catalog_Model_Layer_Filter_Price->_getItemsData()
#11 /var/www/shop-reza.dk/public_html/app/code/core/Mage/Catalog/Model/Layer/Filter/Abstract.php(120): Mage_Catalog_Model_Layer_Filter_Abstract->_initItems()
#12 /var/www/shop-reza.dk/public_html/app/code/core/Mage/Catalog/Model/Layer/Filter/Abstract.php(109): Mage_Catalog_Model_Layer_Filter_Abstract->getItems()
#13 /var/www/shop-reza.dk/public_html/app/code/core/Mage/Catalog/Block/Layer/Filter/Abstract.php(132): Mage_Catalog_Model_Layer_Filter_Abstract->getItemsCount()
#14 /var/www/shop-reza.dk/public_html/app/design/frontend/default/theme213/template/catalog/layer/view.phtml(46): Mage_Catalog_Block_Layer_Filter_Abstract->getItemsCount()
#15 /var/www/shop-reza.dk/public_html/app/code/core/Mage/Core/Block/Template.php(241): include('/var/www/shop-r...')
#16 /var/www/shop-reza.dk/public_html/app/code/core/Mage/Core/Block/Template.php(272): Mage_Core_Block_Template->fetchView('frontend/defaul...')
#17 /var/www/shop-reza.dk/public_html/app/code/core/Mage/Core/Block/Template.php(286): Mage_Core_Block_Template->renderView()
#18 /var/www/shop-reza.dk/public_html/app/code/core/Mage/Core/Block/Abstract.php(919): Mage_Core_Block_Template->_toHtml()
#19 /var/www/shop-reza.dk/public_html/app/code/core/Mage/Core/Block/Text/List.php(43): Mage_Core_Block_Abstract->toHtml()
#20 /var/www/shop-reza.dk/public_html/app/code/core/Mage/Core/Block/Abstract.php(919): Mage_Core_Block_Text_List->_toHtml()
#21 /var/www/shop-reza.dk/public_html/app/code/core/Mage/Core/Block/Abstract.php(637): Mage_Core_Block_Abstract->toHtml()
#22 /var/www/shop-reza.dk/public_html/app/code/core/Mage/Core/Block/Abstract.php(581): Mage_Core_Block_Abstract->_getChildHtml('left', true)
#23 /var/www/shop-reza.dk/public_html/app/design/frontend/default/theme213/template/page/2columns-left.phtml(57): Mage_Core_Block_Abstract->getChildHtml('left')
#24 /var/www/shop-reza.dk/public_html/app/code/core/Mage/Core/Block/Template.php(241): include('/var/www/shop-r...')
#25 /var/www/shop-reza.dk/public_html/app/code/core/Mage/Core/Block/Template.php(272): Mage_Core_Block_Template->fetchView('frontend/defaul...')
#26 /var/www/shop-reza.dk/public_html/app/code/core/Mage/Core/Block/Template.php(286): Mage_Core_Block_Template->renderView()
#27 /var/www/shop-reza.dk/public_html/app/code/core/Mage/Core/Block/Abstract.php(919): Mage_Core_Block_Template->_toHtml()
#28 /var/www/shop-reza.dk/public_html/app/code/core/Mage/Core/Model/Layout.php(555): Mage_Core_Block_Abstract->toHtml()
#29 /var/www/shop-reza.dk/public_html/app/code/core/Mage/Core/Controller/Varien/Action.php(390): Mage_Core_Model_Layout->getOutput()
#30 /var/www/shop-reza.dk/public_html/app/code/core/Mage/Catalog/controllers/CategoryController.php(161): Mage_Core_Controller_Varien_Action->renderLayout()
#31 /var/www/shop-reza.dk/public_html/app/code/core/Mage/Core/Controller/Varien/Action.php(418): Mage_Catalog_CategoryController->viewAction()
#32 /var/www/shop-reza.dk/public_html/app/code/core/Mage/Core/Controller/Varien/Router/Standard.php(250): Mage_Core_Controller_Varien_Action->dispatch('view')
#33 /var/www/shop-reza.dk/public_html/app/code/core/Mage/Core/Controller/Varien/Front.php(172): Mage_Core_Controller_Varien_Router_Standard->match(Object(Mage_Core_Controller_Request_Http))
#34 /var/www/shop-reza.dk/public_html/app/code/core/Mage/Core/Model/App.php(354): Mage_Core_Controller_Varien_Front->dispatch()
#35 /var/www/shop-reza.dk/public_html/app/Mage.php(684): Mage_Core_Model_App->run(Array)
#36 /var/www/shop-reza.dk/public_html/index.php(87): Mage::run('', 'store')
#37 {main}

Actually the filtering works. If I in the file app/design/frontend/default/theme213/template/catalog/layer/view.phtml as the first thing writes <?php die(); ?>, the execution stops before the problematic code. This means that the product listing is displayed (correct with the filters applied), but for example the layered navigation block is removed.

I suspect that the way this filtering is done is horrible wrong with respect to Magento development. Thus, if any of you have a better/preferred way to apply filters on the product listing page (based on some GET parameters), let me know!

Best Answer

Finally got it working, although not in the optimal way.

By tracing the SQL query actually executed by Magento, I noticed that the table it looked in was in catalog_product_flat_1. So, in Configuration → Catalog → Product I disabled Use Flat Catalog Product and then made a reindex.

Related Topic