Magento – Magento 2 – Retrieve categories

categorycategory-treemagento2

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?

Best Answer

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!

Related Topic