1
votes

I have a Magento site with an extensive catalog (10,000 products) and a fairly deep category tree.

All of the product's categories stem from a top-level "All Products" category.
All products have a drop-down attribute of "Brand."

What I am trying to do is allow a visitor to start at the top of the category tree and navigate down the "All Products" tree either with or without the brand selected. The hitch is that we need to show the next level of subcategories at each level and I don't want to show empty categories if a brand doesn't apply.

For example, if the tree looks like this and one is on the "Screwdrivers Page," we'd like both the type and length categories to be visible.

  1. All Products
    • Screw Drivers
      • phillips
        • 2"
        • 3"
        • 5"
      • flathead
        • 1"
        • 3"
        • 5"

I was able do this without worrying about the brand filter by creating a category collection:

    $_category  = $this->getCurrentCategory();
    $current_level = $_category->getLevel(); 
    $collection = $_category->getCollection(); 

    $collection->addAttributeToSelect('url_key')
                ->addAttributeToSelect('name')
                ->addAttributeToSelect('parent_id')
                ->addAttributeToFilter('is_active', 1)
                ->addAttributeToFilter('level',array('in'=>array($current_level+1,$current_level+2)))
                ->setOrder('position','ASC')
                ->load();

Based on my research it appears that it is not possible to directly filter a category collection by a product attribute.

Assuming that this is true: What is the best way to accomplish this? I've thought of and preliminarily tried few ideas:

  • Create a product collection filtered by brand and loop through it to get all of the relevant categories and build the tree (seems like this would be horribly inefficient)
  • Try to utilize layered navigation to output the categories (this would work if we were only viewing one level -- I'm having trouble getting a filtered "second" level.)
  • Abandon the filtering idea and duplicate the category Tree under a new "Browse By Brand" Category (I'd like to stay away from this so that updating products doesn't require updating two duplicate trees.)

Thanks in advance for any help. Please let me know if you need any clarification of the problem.

1

1 Answers

5
votes

In case anyone has a similar issue down the road I accomplished this by using the second bullet point above.

/* Get Current Filters by loading catalog/layer_view Block */
        $layout = Mage::getSingleton('core/layout');
        $block  = $layout->createBlock('catalog/layer_view');           
/*  Get Current Category  */
        $_category  = $this->getCurrentCategory();
        $current_level = $_category->getLevel();
/*  Get Layer Filter Category Model  */
        $category_filter = Mage::getModel('catalog/layer_filter_category');
/*  Generate the collection based on the current category  */
        $categories = $_category->getCollection();
        $categories->addAttributeToSelect('url_key')
                    ->addAttributeToSelect('name')
                    ->addAttributeToSelect('parent_id')
                    ->addAttributeToSelect('thumbnail')
                    ->addAttributeToFilter('is_active', 1)
                    ->addAttributeToFilter('path', array('like'=>'%/'.$_category->getId().'/%'))
                    ->addAttributeToFilter('level',array('in'=>array($current_level+1,$current_level+2)))
                    ->setOrder('position','ASC')
                    ->load();

/*  Using current filters, add product counts to collection so we can hide categories with 0 products  */
        $category_filter->getLayer()->getProductCollection()
            ->addCountToCategories($categories);

After this it is a matter of looping through the collection and displaying the name, URL of the category, etc..

This may not be the absolute best way -- I certainly welcome other solutions.