Magento – Get Product Current Subcategory of Specific Parent Category

categoryproduct

I need to find a solution to get product current subcategory from specific parent category.

For example: I have a product that has like 2 parent categories like authors and publishers. And in those i have like 500-800 subcategories, and this product has one of subcategories in each parent categories selected. I need to get those subcategory names. My solution:

function getSubsName($_product,$cat_id)
    {
        $categories = $_product->getCategoryIds(); 
        $cat = Mage::getModel('catalog/category')->load($cat_id); 
        $subcats = $cat->getChildren(); 
        $content = "";
        foreach(explode(',',$subcats) as $subCatid):
           $_category = Mage::getModel('catalog/category')->load($subCatid);
           foreach($categories as $cat_id):
              if($cat_id == $_category->getId()):
                  $content = '<a href="' . $_category->getUrl() .'">' .      $_category->getName() . '</a>';
              endif;
           endforeach;
        endforeach;
        return $content;
    }

But there is a problem because it loads very long. Like 8-10 seconds or more. I can't afford that. Anyone know any more simple and fast solution for this?

Best Answer

One reason for it going slow is the number of loads you are doing in a loop. Also you are loading the initial category when you do not need to.

I have taken the liberty of refactoring your function. Hope you don't mind :)

function getSubsName($product, $parentId)
{
    $content = "";

    // get the product categories
    $categories = $product->getCategoryIds();

    // get all children of the parent $parentId
    $children = Mage::getModel('catalog/category')->getCategories($parentId, 0, false, true);
    foreach ($children as $category) {

        // if the child is in the product categories,
        // include it
        if (in_array($category->getId(), $categories)) {
            $content .= '<a href="'.$category->getUrl().'">'.$category->getName().'</a>';
        }
    }

    return $content;
}