0

I am trying to get all products of specific category whether these products are directly listed in the category or in the subcategories under this specific category I really searched for this on google and Magento Stack Exchange and found nothing about Magento 2, all I found are some topics on Magento 1,

Here is What I just reached,

use Magento\Framework\App\Action\Action;
use Magento\Framework\App\Action\Context;
use Magento\Framework\Controller\Result\JsonFactory;
use Magento\Catalog\Model\ResourceModel\Product\CollectionFactory;

class ChildProducts extends Action
{
    protected $resultJsonFactory;
    protected $_categoryFactory;
    protected $productCollectionFactory;
    public function __construct(Context $context, JsonFactory $jsonFactory ,\Magento\Catalog\Model\CategoryFactory $categoryFactory ,
    CollectionFactory $productCollection)
    {
        $this->_categoryFactory = $categoryFactory;
        $this->resultJsonFactory = $jsonFactory;
        $this->productCollectionFactory = $productCollection;
        parent::__construct($context);
    }

    public function execute()
    {
        // get parent category
        $categoryId = $this->getRequest()->getParam('category_id');


        $productCollection = $this->productCollectionFactory->create();
        $productCollection->addAttributeToSelect('*');
        $productCollection->addCategoriesFilter(array('in' => $categoryId));
        return $this->resultJsonFactory->create()->setData($productCollection);
    }

3 Answers 3

1

Inject \Magento\Catalog\Api\CategoryManagementInterface $obj in to your file and create object $this->_obj

Then in your method use this object to get tree

if(your category_id)
        {
            $depth = 5;
            $cat = $this->_obj->getTree("your category_id", $depth);
            $this->getSubCategories($cat);
        }

Create a Recursive fuction name public function getSubCategories($child_detail)

     public function getSubCategories($child_detail)
            {
                $subCats = $child_detail->getChildrenData();
                       if ($subCats) {

                    foreach ($subCats as $subcat) {
                            //your category tree with subcategories
                              echo  $child_name = $subcat->getName();

        //for products in a category inject di of class ***\Magento\Framework\App\ResourceConnection $resourceConnection*** use it with object ***$this->_resources***

                                  $connection= $this->_resources->getConnection();

        //create a custom query to get all products along with their child products otherwise child products won't appear

                                 $select = $connection->select()
                                     ->from(['o' =>  $this->_resources->getTableName('catalog_category_product')]);
                                 $select->where('category_id = ?', $subcat->getId());

                                 $result = $connection->fetchAll($select);


//All category product_ids are in $result to deal it with separate save separately
                                 $proIds = array();
                                 foreach ($result as $product)
                                 {
                                     $proIds[] = $product['product_id'];
                                 }

//inject ***\Magento\Catalog\Model\ResourceModel\Product\CollectionFactory $productFactory*** and create object ***$this->productFactory*** to load your category product from all products or you can say filter your products from all products
         $collect = $this->productFactory->create()->addFieldToFilter('entity_id',array('in',$proIds));
                                 foreach ($collect as $product)
                                 {
                                    //do what ever you like with product
                                   echo $product->getId();
                                 }

            $this->getSubCategories($subcat);
                    }

hope that helps

2
  • thank you a lot you really helped me figure out a solution and i will post it as an answer here
    – mahmudy-91
    Apr 10, 2019 at 10:35
  • no problem. if this helps then give a vote .thanks
    – Asad Ullah
    Apr 11, 2019 at 9:08
0

To get All Product Based On Category Id :-

protected $_productCollectionFactory;
protected $_categoryFactory;

public function __construct(
    \Magento\Catalog\Model\ResourceModel\Product\CollectionFactory $productCollectionFactory,
    \Magento\Catalog\Model\CategoryFactory $categoryFactory,
    \Magento\Framework\View\Element\Template\Context $context,
) {
    $this->_categoryFactory = $categoryFactory;
    $this->_productCollectionFactory = $productCollectionFactory;
    parent::__construct($context);
}

public function getProductCollection()
{
    $categoryId = 'yourcategoryid';
    $category = $this->_categoryFactory->create()->load($categoryId);
    $collection = $this->_productCollectionFactory->create();
    $collection->addAttributeToSelect('*');
    $collection->addCategoryFilter($category);
    return $collection;
}
0

here is what i just reached , all i needed to do to get all the products data from parent category and its all sub categories to the last level was that , here is the code

use Magento\Framework\App\Action\Action;
use Magento\Framework\App\Action\Context;
use Magento\Framework\Controller\Result\JsonFactory;
use Magento\Catalog\Model\ResourceModel\Product\CollectionFactory;
use Magento\Catalog\Api\CategoryManagementInterface;
use Magento\Catalog\Model\ResourceModel\Category\CollectionFactory as CategoryCollectionFactory;

class ChildProducts extends Action
{
    protected $resultJsonFactory;
    protected $_categoryFactory;
    protected $productCollectionFactory;
    protected $allProducts = [];
    protected $cats = [];
    protected $_obj;
    protected $categoryCollectionFactory;
    public function __construct(Context $context, JsonFactory $jsonFactory ,\Magento\Catalog\Model\CategoryFactory $categoryFactory ,
    CollectionFactory $productCollection , CategoryManagementInterface $obj ,
    CategoryCollectionFactory $categoryCollectionFactory)
    {
        $this->_categoryFactory = $categoryFactory;
        $this->resultJsonFactory = $jsonFactory;
        $this->productCollectionFactory = $productCollection;
        $this->_obj = $obj;
        $this->categoryCollectionFactory = $categoryCollectionFactory;
        parent::__construct($context);
    }

    public function execute()
    {
        // get parent category
        $categoryId = $this->getRequest()->getParam('category_id');
        $this->getCats($categoryId);
        foreach($this->cats as $cat)
        {
            $this->getProductCollection($cat);
        }
        //$this->getProductCollection($categoryId);
        return $this->resultJsonFactory->create()->setData($this->allProducts);
    }

    public function getCats($categoryId)
    {
        $_category = $this->_categoryFactory->create();

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

        //Get category collection
        $collection = $category->getCollection()
                ->addIsActiveFilter()
                ->addOrderField('name')
                ->addIdFilter($category->getChildren());
                $cats = [];
        foreach($collection as $coll)
        {
            $cats[] = $coll['entity_id'];
            $this->cats[] = $coll['entity_id'];
        }
        foreach($cats as $cat)
        {
            $catfactory = $this->_categoryFactory->create();
            $catobj = $catfactory->load($cat);
            if(!$catobj->hasChildren())
            {
                continue;
            }else{
                $this->getCats($cat);
            }
        }
    }

    public function getProductCollection($categoryId)
    {
        $category = $this->_categoryFactory->create()->load($categoryId);
        $collection = $this->productCollectionFactory->create();
        $collection->addAttributeToSelect('*');
        $collection->addCategoryFilter($category);
        // return $collection;
        foreach ($collection as $product)
        {
            $this->allProducts[] = ["name" => $product->getName() , "id" => $product->getId() , "price" => $product->getPrice()];
        }
    }
3
  • you can't get all products (child products) like "child products of configurable products and group products" by using category filter you need to add a custom query for this
    – Asad Ullah
    Apr 12, 2019 at 10:12
  • i will not use configurable product in my application, thanks for the tip, so i can say that this solution is only for simple products
    – mahmudy-91
    Apr 12, 2019 at 12:38
  • yes you can say that .
    – Asad Ullah
    Apr 14, 2019 at 15:01

Your Answer

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

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