Magento – Get subcategories of parent category when FLAT categories enabled

categoryflat-catalogmodelnavigationsubmenu

I override a block class Mage_Catalog_Block_Navigation (link to signature) to create a custom menu which displays only subcategories of current category.

Inside method renderCategoriesMenuHtml (link to signature) I'm trying to get child categories of selected parent category. So I replaced default code:

foreach ($this->getStoreCategories() as $child) {
    //...
}

with the following:

/**
 * @param $parent ID of category from which we start
 * @param $recursionLevel How many levels of subcategories retrieve
 * getCategories(...) is a method from model Mage_Catalog_Model_Category
 */
$category = Mage::getModel('catalog/category');
$storeCategories = $category->getCategories($parent, $recursionLevel);
foreach ($storeCategories as $child) {
    //...
}

This code works perfectly fine and returns subcategories of selected parent, but as soon as I enable the "Flat Catalog Category" the $parent variable seems to be completely ignored and that code returns all top-level categories, instead of subcategories of category with ID $parent.

What do I do wrong? Shouldn't getCategories method work the same even when flat categories are enabled?

EDIT:

My real question is

  1. Why method getCategories from model Mage_Catalog_Model_Category
    ignors parameters $parent and $recursionLevel when flat
    categories are enabled? (see source of the method below)
  2. Are there more methods which works different with flat catalog? How
    can I recognize them to avoid problems in the future?

I call it like this inside method renderCategoriesMenuHtml:

$parent = 13;
$recursionLevel = 2;
$category = Mage::getModel('catalog/category');
$storeCategories = $category->getCategories($parent, $recursionLevel);

With non-flat categories this code returns subcategories (2 levels as specified in $recursionLevel) of the category with ID 13.
But with flat categories enabled I get all top-level categories with all subcategories (limited with value of admin settings 'catalog/navigation/max_depth', not by $recursionLevel).

Method in model Mage_Catalog_Model_Category:

public function getCategories($parent, $recursionLevel = 0, $sorted=false, $asCollection=false, $toLoad=true)
{
    $categories = $this->getResource()
        ->getCategories($parent, $recursionLevel, $sorted, $asCollection, $toLoad);
    return $categories;
}

calls method in resource model Mage_Catalog_Model_Resource_Category:

public function getCategories($parent, $recursionLevel = 0, $sorted = false, $asCollection = false, $toLoad = true)
{
    $tree = Mage::getResourceModel('catalog/category_tree');
    /* @var $tree Mage_Catalog_Model_Resource_Category_Tree */
    $nodes = $tree->loadNode($parent)
        ->loadChildren($recursionLevel)
        ->getChildren();

    $tree->addCollectionData(null, $sorted, $parent, $toLoad, true);

    if ($asCollection) {
        return $tree->getCollection();
    }
    return $nodes;
}

Best Answer

$_category = Mage::getModel('catalog/category')->load(CATEGORY-ID);    
    $_categories = $_category
                    ->getCollection()
                    ->addAttributeToSelect(array('name', 'image', 'description'))
                    ->addIdFilter($_category->getChildren());

    foreach ($_categories as $_category):
       echo $_category->getName();
    endforeach;