Magento – On Search Result: Group Products by Category

catalogsearchmagento-1product-list

I need the search result page to list products grouped by category name.

Example: When searching for nike the result should be viewed like this:

Category "Shoes":
  - some nike shoe
  - another nike shoe

Category "Shirts":
  - some nike shirt
  - another nike shirt
  - ..

Category ...
  - ...

So far I tried to modify my list.phtml to simply cycle through all active store categories and check each found product (from getLoadedProductCollection()) if its assigned to that category. It's working, but slow as hell. So I think there must be some more Magento-like way to do this, but I don't know where to start. Anyone got some tip for me? Thanks

Best Answer

I've used the Display Products Grouped By Subcategories extension on category list pages before with success.

Another solution before we found this extension was to get the collection in the block and use a special attribute to order the collection. The code was as follows (only works under PHP 5.3)

class Class_Name
{
    [...]
    protected function _getProductCollection()
    {
        [...]

        $collection = $this->_productCollection;

        $collection->addAttributeToSelect('category_sort_value');


        // Do some fancy sorting
        $collectionReflection = new ReflectionObject($collection);
        $itemsPropertyReflection = $collectionReflection->getProperty('_items');
        $itemsPropertyReflection->setAccessible(true); // Make it accessible

        $collectionItems = $itemsPropertyReflection->getValue($collection);

        usort($collectionItems, array("Class_Name", "cmp"));

        $itemsPropertyReflection->setValue($collectionReflection, $collectionItems);

        $itemsPropertyReflection->setAccessible(false); // Return restriction back
        // End them fancyness

        $this->_productCollection = $collection;

        return $this->_productCollection;
    }

    public function cmp($a, $b) 
    {
        $a_sort = (int)$a->getData('category_sort_value');
        $b_sort = (int)$b->getData('category_sort_value');

        if ($a_sort == $b_sort) return 0;
        return ($a_sort < $b_sort) ? -1 : 1;
    }
}

You can use this class example to extend the Block class for the product list in search and sort the results like that. I hope this will help you in the right direction.

Related Topic