0

I'm trying to receive all children categories from a root categorie. I have flat categories enabled.

The problem is that this categorie is not my store root category. I have a main menu (store root category) and a sidebar (another root category). For the sidebar I want to receive the child categories.

What I did so far:

$category = $this->_categoryFactory->create();
$storeCategories = $category->getCategories($this->getSelectedRootCategory(), $recursionLevel = 1, $sorted, $asCollection, $toLoad);

This does fetch all categories, but these are the categories from the store root category.

If I take a look at the getCategories function (in Magento\Catalog\Model\ResourceModel\Category\Flat) I know why: getCategories calls the function getNodes:

public function getNodes($parentId, $recursionLevel = 0, $storeId = 0)
{
    if (!$this->_loaded) {
        $selectParent = $this->getConnection()->select()->from(
            $this->getMainStoreTable($storeId)
        )->where(
            'entity_id = ?',
            $parentId
        );
        if ($parentNode = $this->getConnection()->fetchRow($selectParent)) {
            $parentNode['id'] = $parentNode['entity_id'];
            $parentNode = $this->_categoryFactory->create()->setData($parentNode);
            $this->_nodes[$parentNode->getId()] = $parentNode;
            $nodes = $this->_loadNodes($parentNode, $recursionLevel, $storeId);
            $childrenItems = [];
            foreach ($nodes as $node) {
                $pathToParent = explode('/', $node->getPath());
                array_pop($pathToParent);
                $pathToParent = implode('/', $pathToParent);
                $childrenItems[$pathToParent][] = $node;
            }
            $this->addChildNodes($childrenItems, $parentNode->getPath(), $parentNode);
            $childrenNodes = $this->_nodes[$parentNode->getId()];
            if ($childrenNodes->getChildrenNodes()) {
                $this->_nodes = $childrenNodes->getChildrenNodes();
            } else {
                $this->_nodes = [];
            }
            $this->_loaded = true;
        }
    }
    return $this->_nodes;
}

This function has a check $this->_loaded. If my Sidebar block calls the getCategories function it returns the categories from the root category because these are already loaded.

What is the best way to retrieve my categories? I can reset the _loaded var from a plugin, but I don't think it's the right way to handle this.

Update

The function getNodes starts with

$selectParent = $this->getConnection()->select()->from(
            $this->getMainStoreTable($storeId)
        )->where(
            'entity_id = ?',
            $parentId
        );

that uses $this->getMainStoreTable($storeId).

This returns the flat category table. Because my other category is not the store's root category it's not present in this table. That's why my category is not found. How can I prevent this?

1

You can retrieve category collection and its products of particular main category as below,

$objectManager = \Magento\Framework\App\ObjectManager::getInstance();
$categoryCollection = $objectManager->create('Magento\Catalog\Model\Category');
$category = $categoryCollection->load($rootcat_id);

here you will get main category info then further you can load other sub categories and also product information resided in those categories too.

I hope this helps!

  • Thanks for your reply. Maybe I'm doing something wrong, but when I try to load a root category that is not the store's root category this does not work. For example, I try to load a category with id 3. When this is not set as store root category, the load does not return the proper category. If I change the store's root category to the category with id 3, it does work. – Silvan Mar 15 '16 at 9:52

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.