7

How can I retrieve a product collection by a root category and from all its subcategories?

Eg:

Root Category (2 products)

  • Subcategory 1 (2 products)
  • Subcategory 2 (3 products)

So I want to retrieve all 7 products in the collection.

5 Answers 5

3

You can use like this:

/** \Magento\Catalog\Api\CategoryRepositoryInterface */
protected $categoryRepository;

/** \Magento\Catalog\Model\ResourceModel\Product\CollectionFactory */
protected $productCollectionFactory;

public function getAllProductOfSubcategories($categoryId, $storeId = null) {

    /** @var $result \Magento\Catalog\Model\ResourceModel\Product\Collection */
    $result = $this->productCollectionFactory->create();

    //get category at $storeId 
    try {
        $category = $this->categoryRepository->get($categoryId, $storeId);
    } catch (\Magento\Framework\Exception\NoSuchEntityException $noSuchEntityException) {
        return null;
    }

    return $result->addCategoryFilter($category);
}

*Note: Your category must Enable Anchor

Enable Anchor for Category

*Note: run php bin/magento indexer:reindex just for make sure

2

Code for your class file:

protected $_categoryHelper;
protected $_categoryRepository;

public function __construct(
    \Magento\Catalog\Helper\Category $categoryHelper,
    \Magento\Catalog\Model\CategoryRepository $categoryRepository,
    array $data = []
)
{
    $this->_categoryHelper = $categoryHelper;
    $this->_categoryCategoryRepository = $categoryRepository;        
    parent::__construct($context, $data);
}

public function getStoreCategories() 
{
    return $this->_categoryHelper->getStoreCategories();
}

public function getCategory($categoryId)
{
    return $this->_categoryRepository->get($categoryId);
}

Code for your template file:

$categories = $block->getStoreCategories();
foreach ($categories as $category) {
    echo $category->getName();
    echo ' ( ' . $category->getProductCount() . ' )';

    $subCategories = $block->getCategory($category->getId());
    foreach ($subCategories as $subCategory) {
        echo $subCategory->getName();
        echo ' ( ' . $subCategory->getProductCount() . ' )';
    }
}

Source: Magento 2: Get parent category, children categories & product count

1

I solved it as below,

protected $_category;
protected $_productCollection;

/** You should provide your root category here, and it will return comma seperated sub category list */
public function getChildren($categoryId = false)
{
    if ($this->_category) {
        return $this->_category->getChildren();
    } else {
        return $this->getCategory($categoryId)->getChildren();
    }        
}    

protected function _getProductCollection()
{
    $childListStr   = $this->getChildren( 2 ); // Provide the root category ID
    $childList      = explode( ",", $childListStr );
    $catToLoad      = array();

    foreach( $childList as $item ){
        array_push( $catToLoad, $item );
    }

    if ($this->_productCollection === null) {
        $layer = $this->getLayer();
        $this->_productCollection = $layer->getProductCollection();            
    }

    $this->_productCollection->addCategoriesFilter(['in' => $catToLoad ]);  
    return $this->_productCollection;
}
0

Hi I have another way to get product collection from root category... check it out.. I hope this help

public function __construct(
    \Magento\Catalog\Model\Layer\Category $categoryLayer    
){
      $this->_categoryLayer = $categoryLayer;
}

public function getProductCollection($category){
     return $this->_categoryLayer->setCurrentCategory($category)->getProductCollection();
}
-6

Try this

 $category = Mage::getModel('catalog/category')->load(2);
 $children = Mage::getModel('catalog/category')->getCollection()->setStoreId(Mage::app()->getStore()->getId());
 $children->addAttributeToSelect('*')
          ->addAttributeToFilter('parent_id', $category->getId())
          ->addAttributeToFilter('is_active', 1)
          ->addAttributeToSort('position');
foreach($children as $child)
{

   $category=Mage::getModel('catalog/category')->load($child->entity_id);
}
1

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.