11

What I'd like to do is grab all of the child categories of a specific parent category. I'm assuming the best way to do this is by using the parent's ID and of those child categories that are returned, I'd like to grab their child categories as well.

2

7 Answers 7

22

Check below example to list of all subcategories of specific parent category using parent category ID using the repository.

First of all add CategoryRepository in construct:

<?php
    protected $categoryRepository;
    
    public function __construct(
        \Magento\Catalog\Model\CategoryRepository $categoryRepository
    ) {
        $this->categoryRepository = $categoryRepository;
    }
?>

Now you can use the following way:

<?php
    $categoryId = [YOUR_CATEGORY_ID];
    $category = $this->categoryRepository->get($categoryId);
    $subCategories = $category->getChildrenCategories();
    foreach($subCategories as $subCategory) {
        echo $subCategory->getName();

        /* For Sub Categories */
        if($subcategorie->hasChildren()) {
        $childCategoryObj = $this->categoryRepository->get($subCategory->getId());
        $childSubcategories = $childCategoryObj->getChildrenCategories();
        foreach($childSubcategories as $childSubcategory) {
            echo $childSubcategory->getName();
        }
     }
    }
?>
2
  • 2
    work for me...!
    – Devidas
    Commented Sep 25, 2018 at 10:40
  • replace subcategorie with subCategory Commented Oct 19, 2021 at 11:54
19

You need to add a dependency to your class \Magento\Catalog\Model\ResourceModel\Category\CollectionFactory.

Like this:

protected $categoryCollectionFactory;
public function __construct(
    ...
    \Magento\Catalog\Model\ResourceModel\Category\CollectionFactory $categoryCollectionFactory,
    ...
) {
    ...
    $this->categoryCollectionFactory = $categoryCollectionFactory;
    ...
}
public function getDescendants($category, $levels = 2)
{
    if ((int)$levels < 1) {
        $levels = 1;
    }
    $collection = $this->categoryCollectionFactory->create()
          ->addPathsFilter($category->getPath().'/') 
          ->addLevelFilter($category->getLevel() + $levels);
    return $collection;
}

now you just need to call the method getDescendants with the $category object as a parameter and the number of levels you need for subcategories (2 in your case).

4
  • I'm giving this a shot, but can you clarify what code should be used in the phtml file?
    – Paul
    Commented Jul 15, 2016 at 15:11
  • you need to add this code to your block class, and in your phtml you can use $block->getDescendents($category, 2) where $category is the main category. (I don't know where you get that from).
    – Marius
    Commented Jul 15, 2016 at 15:19
  • @Marius Hey Marius, I know an old post but how does one work out what should be where the ... are? Commented Sep 16, 2019 at 10:12
  • @Marius Super answer (y) Commented Feb 28, 2020 at 7:11
12

Always try to use repository. Here is an example.

Inject CategoryRepository by construct

protected $categoryRepository;

public function __construct(
    \Magento\Catalog\Model\CategoryRepository $categoryRepository
) {
    $this->categoryRepository = $categoryRepository;
}

Now you can use following way:

$parent_category_id = 3;
$categoryObj = $this->categoryRepository->get($parent_category_id);
$subcategories = $categoryObj->getChildrenCategories();
foreach($subcategories as $subcategorie) {
    echo '    --> '.$subcategorie->getName().'<br/>';
}

For 2 level child category:

$categoryObj = $this->categoryRepository->get($parent_category_id);
$subcategories = $categoryObj->getChildrenCategories();
foreach($subcategories as $subcategorie) {
    echo '    --> '.$subcategorie->getName().'<br/>';
    if($subcategorie->hasChildren()) {
        $childCategoryObj = $this->categoryRepository->get($subcategorie->getId());
        $childSubcategories = $childCategoryObj->getChildrenCategories();
        foreach($childSubcategories as $childSubcategorie) {
            echo '        --> '.$childSubcategorie->getName().'<br/>';
        }
    }
}
3
  • this will get you only 1 level of subcategories. The OP asked for 2 levels.
    – Marius
    Commented Jul 15, 2016 at 14:53
  • 1
    Even better than using the repository model directly, use the interface. \Magento\Catalog\Api\CategoryRepositoryInterface
    – Andrei
    Commented Oct 1, 2017 at 10:44
  • How to limit getChildrenCategories to 4 only? I need first 4 children categories of parent category Commented Nov 10, 2018 at 7:43
3

Use below code to get all active child categories of a specific category.

Function getChildCategories($categoryId) gives all child categories. Where $categoryId - is parent category id

<?php
namespace YourModuleName\CategoryLink\Block;

use Magento\Framework\View\Element\Template;
use Magento\Framework\View\Element\Template\Context;
use Magento\Catalog\Model\CategoryFactory;


/**
 * Category link block
 */
class Link extends Template
{
    /**
     * @var Magento\Catalog\Model\CategoryFactory
     */
    protected $_categoryFactory;


    /**
     * 
     * @param Context $context
     * @param array $data
     */
    public function __construct(
        Context $context, 
        CategoryFactory $categoryFactory,
        array $data = []
    ) {
        parent::__construct($context, $data);
        $this->_categoryFactory = $categoryFactory;
      }

    /**
     * Get children categories 
     * 
     * @param $categoryId Parent category id
     * @return Magento\Catalog\Model\ResourceModel\Category\Collection
     */
    public function getChildCategories($categoryId)
    {

        $_category = $this->_categoryFactory->create();

        $category = $_category->load($categoryId);

        //Get category collection
        $collection = $category->getCollection()
                ->addIsActiveFilter()
                ->addOrderField('name')
                ->addIdFilter($category->getChildren());
        return $collection;
    }

} 

$category->getChildren() - This will gives all chid categories ids.

2
    $objectManager = \Magento\Framework\App\ObjectManager::getInstance();
    $category = $objectManager->get('Magento\Framework\Registry')->registry('current_category');//get current category 
    $catId = $category->getId(); // Parent Category ID
        $subcategory = $objectManager->create('Magento\Catalog\Model\Category')->load($catId);
$subcats = $subcategory->getChildrenCategories();
        $categoryHelper = $this->getCategoryHelper();    
    <div class="category_bg mobile">
            <ul id="main_cat_bg" class="main_cat_bg">
                <?php
                $cat_togg = 0;
                foreach ($subcats as $subcat) {
                    if (!$subcat->getIsActive()) {
                        continue;
                    }
                    $_category = $objectManager->create('Magento\Catalog\Model\Category')->load($subcat->getId());
                    //$_outputhelper = $this->helper('Magento\Catalog\Helper\Output');
                    $helper    = $this->helper('SR\CategoryImage\Helper\Category');
                    $subcaturl = $subcat->getUrl();
                    $imageUrlthum = $helper->getImageUrl($_category->getData('thumbnail'));
                    //$imageUrlthum = resize($_category->getData('thumbnail'),153,153);
                    //$cat_desc = $_category->getCatDescription();
                    $_imgHtml = '';
                    if ($imageUrlthum) {
                        $_imgHtml = '<img src="' . $imageUrlthum. '" />';

                        //$_imgHtml = $_outputhelper->categoryAttribute($_category, $_imgHtml, 'image');
                /* @escapeNotVerified */
                    } 
                    ?>
                    <li>
                        <div class="sub_cat_content_main">
                            <div class="cat_image_text">
                                <a href="<?php echo $subcaturl ?>">
                                    <?php echo $_imgHtml;?>
                                    <!--<div class="desicription_part">-->
                                    <?php //echo $cat_desc; ?>
                                    <!--</div>-->
                                </a>
                               <div class="sub_name_bg">                
                                    <a href="<?php echo $subcaturl ?>">
                                        <?php echo $subcat->getName(); ?>
                                    </a>
                                </div>
                                <!-- Start 3rd Level Chiled Category-->
                                <?php
                                    $objectManager = \Magento\Framework\App\ObjectManager::getInstance();
                                    $object_managertwo = $objectManager->create('Magento\Catalog\Model\Category')->load($subcat->getId());
                                    $subcatslevelthird = $object_managertwo->getChildrenCategories();
                                ?>
                                <?php if ($subcatslevelthird->count() > 0) { ?>
                                <ul class="sub_cat_bg">
                                    <?php
                                    foreach ($subcatslevelthird as $subcatthird) {
                                        $_outputhelper = $this->helper('Magento\Catalog\Helper\Output');
                                        $subcaturl = $subcatthird->getUrl();
                                        ?>
                                        <li class="cat_image_bg">
                                            <a class="level-top" href="<?php //echo $subcaturl ?>">
                                                <span><?php //echo $subcatthird->getName(); ?></span>
                                            </a>
                                            <div class="child_name_bg">
                                                <span><?php echo $subcatthird->getName(); ?></span>
                                            </div>

                                        <!-- Start 4th Level Chiled Category-->
                                        <?php
                                            $_objectManager = \Magento\Framework\App\ObjectManager::getInstance();
                                            $object_managerthree = $_objectManager->create('Magento\Catalog\Model\Category')->load($subcatthird->getId());
                                            $subcatslevel = $object_managerthree->getChildrenCategories();
                                        ?>
                                        <?php if ($subcatslevel->count() > 0){?>
                                        <ul class="chiled_cat_bg">
                                            <?php
                                            foreach ($subcatslevel as $subcatlevel) {
                                                $_outputhelper = $this->helper('Magento\Catalog\Helper\Output');
                                                $subcaturl = $subcatlevel->getUrl();
                                                ?>
                                                <li class="cat_image_bg">
                                                    <a class="level-top" href="<?php echo $subcaturl ?>">
                                                        <span><?php echo $subcatlevel->getName(); ?></span>
                                                    </a>
                                                </li>

                                            <?php } ?>
                                        </ul>
                                        <?php } ?>
                                        <!-- End 4th level Chiled Category-->
                                        </li>
                                    <?php } ?>
                                </ul>
                                <?php } ?>
                                <!-- End 3rd level Chiled Category-->
                            </div>
                        </div>
                    </li>
                <?php } ?>
            </ul>
             <div id="view_more">
                View more
            </div>
        </div>
2
  • I want to be sorted children categories, by category name, please help on this? Commented Aug 9, 2019 at 12:05
  • You need to use and get category id for name of category Commented Sep 2, 2019 at 8:05
1

-> Get all level subcategories from parent category

$categoryId = 58;
allCategories($categoryId);
function allCategories($categoryId) {
    $objectManager =  \Magento\Framework\App\ObjectManager::getInstance();
    $categoryFactory = $objectManager->get('\Magento\Catalog\Model\CategoryFactory');

    // Load category by category ID
    $category = $categoryFactory->create()->load($categoryId);
    echo "<pre>"; print_r($category->getData());

    // Get comma-separated children category ids
    $childrenCategoryIds = $category->getChildren($categoryId);
    echo $childrenCategoryIds;

    //Get all children category ids ids comma-separated
    $allChildrenCategoryIds = $category->getAllChildren(false);
    echo $allChildrenCategoryIds;

    //Get all children category ids as an array
    $allChildrenCategoryIdsArr = $category->getAllChildren(true);
    echo "<pre>"; print_r($allChildrenCategoryIdsArr);

    $allChildCategories = allChildLoop($category);
    echo "<pre>"; print_r($allChildCategories);

}

function allChildLoop($category) {
    $idsArray = $category->getAllChildren(true);
    $objectManager =  \Magento\Framework\App\ObjectManager::getInstance();
    $categoryFactory = $objectManager->get('\Magento\Catalog\Model\CategoryFactory');
    $collection = $categoryFactory->create()->getCollection()->addAttributeToSelect('*')->addAttributeToFilter('is_active', 1)->setOrder('position', 'ASC')->addIdFilter($idsArray);
    $categoryNames = array();
    foreach ($collection as $key => $category) {
        $categoryNames[] = $category->getName();
    }
    return $categoryNames;
}
0
<?php

    // \Magento\Catalog\Model\CategoryFactory $categoryFactory 
    // \Magento\Catalog\Model\ResourceModel\CategoryFactory $categoryResourceFactory,
    // \Magento\Store\Model\StoreManagerInterface $storeManager,

public function getStoreBasedCategories($storeId)
{

    $category = $this->categoryFactory->create();
    $storeRootCategoryId = $this->storeManager->getStore($storeId)->getRootCategoryId();

    $storeRootCategory = $category->load($storeRootCategoryId);
    $categoryResource = $this->categoryResourceFactory->create();
    $childrenCategories = $categoryResource->getChildren($storeRootCategory, true);

    foreach($childrenCategories as $categoryId) {
        $category = $this->categoryFactory->create();
        $storeCategories[] = $category->load($categoryId);
    }

    return $storeCategories;
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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