Magento – Get child categories tree when Flat Catalog Category is enabled in admin in Magento 2

categorycategory-treeflat-catalogmagento2

How to get child categories from selected parent category when "Use
Flat Catalog Category" is enabled?

I need to create a small menu which displays all sub-categories of current category in a custom menu.

To get sub-categories of the current category, I extended class Magento\Catalog\Block\Navigation and created a method which returns sub-categories (identifier of the current category is passed in $parent parameter):

namespace Company\MyNav\Block;
class MyNav extends \Magento\Catalog\Block\Navigation
{
    public function getCategoryChildren($parent)
    {
        $category = ObjectManager::getInstance()->create('Magento\Catalog\Model\Category');
        $subCategories = $category->getCategories($parent);
        return $subCategories;
    }
    // ...
}

It all works great, method getCategories from Magento\Catalog\Model\Category returns all sub-categories (also from all lower levels) of the selected parent category.

But as soon as I enable "Use Flat Catalog Category" option in admin, method getCategories returns entire tree of categories instead of only the children of the selected category.

  1. Shouldn't the same code give the same results no matter if flat categories are enabled or disabled? Is this a bug in Magento 2?

  2. Are there any additional steps needed to make this code work even flat categories field is enabled?

Best Answer

You can use getChildren to get child category data in your block even Use Flat Catalog Category is enabled.

For example

namespace Custom\Module\Block\World;
class Index extends \Magento\Framework\View\Element\Template
{
    protected $_categoryFactory;
    protected $_category;
    protected $_categoryHelper;
    protected $_categoryRepository;

    public function __construct(
        \Magento\Backend\Block\Template\Context $context,        
        \Magento\Catalog\Model\CategoryFactory $categoryFactory,
        \Magento\Catalog\Helper\Category $categoryHelper,
        \Magento\Catalog\Model\CategoryRepository $categoryRepository,        
        array $data = []
    )
    {
        $this->_categoryFactory = $categoryFactory;        
        parent::__construct($context, $data);
    }
        /**
     * Get category object
     * Using $_categoryFactory
     *
     * @return \Magento\Catalog\Model\Category
     */
    public function getCategory($categoryId) 
    {
        $this->_category = $this->_categoryFactory->create();
        $this->_category->load($categoryId);        
        return $this->_category;
    }


    /**
     * Retrieve children ids comma separated
     *
     * @return string
     */
    public function getChildren($categoryId = false)
    {
        if ($this->_category) {
            return $this->_category->getChildren();
        } else {
            return $this->getCategory($categoryId)->getChildren();
        }        
    }  



}

Inside the phtml template.

$test =  $block->getChildren('20');
echo "<pre>";
print_r($test);

Out put

enter image description here

Reference link for more details.

Recommended to pass classes to constructor as a dependency.

Hope it helps.