6

We are trying to get product collection by category id.

Block:

protected $_categoryFactory;

public function __construct(
    \Magento\Backend\Block\Template\Context $context,       
    \Magento\Catalog\Model\CategoryFactory $categoryFactory,
    array $data = []
)
{   
    $this->_categoryFactory = $categoryFactory;
    parent::__construct($context, $data);
}

public function getCategory($categoryId) 
{
    $category = $this->_categoryFactory->create();
    $category->load($categoryId);
    return $category;
}

public function getCategoryProducts($categoryId) 
{
    $products = $this->getCategory($categoryId)->getProductCollection();
    $products->addAttributeToSelect('*');
    return $products;
}  

and in html:

$categoryId = 6; // fetching products in category id 6
$categoryProducts = $block->getCategoryProducts($categoryId);
foreach ($categoryProducts as $product) {
    echo $product->getName() . ' - ' . $product->getProductUrl() . '<br />';
}

it works fine only if $categoryId = the highest level in the category tree. But if I change $categoryId to 2 (or 3... or etc but not last in category tree) it doesn't work.

How can I get it work?

3
  • $categoryId = 2 means it is root category. so it will not work for it. Commented Apr 14, 2016 at 13:10
  • or 3... or etc but not last in category tree. it's not working.
    – PolyakovAO
    Commented Apr 14, 2016 at 14:53
  • are the products directly assigned to the categories? I'm asking because categories have the is_anchor switch which shows all products of all child categories on the category page, but I'm pretty sure those products are not assigned directly to the category. So lodaing the products of a category with the is anchor switch active will still only load the products which are directly assigned to the category while the category page will still render all products of all child categories Commented Apr 14, 2016 at 18:40

2 Answers 2

8

I did this task in this way: In block:

protected $_objectManager = null;
protected $_categoryFactory;
protected $_category;
protected $_productCollectionFactory;

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


public function getCurrentCategory()
{
    $category = $this->_objectManager->get('Magento\Framework\Registry')->registry('current_category');
    return $category;
}

/**
 * Get category object
 *
 * @return \Magento\Catalog\Model\Category
 */
public function getCategory($categoryId)
{
    $this->_category = $this->_categoryFactory->create();
    $this->_category->load($categoryId);
    return $this->_category;
}

/**
 * Get all children categories IDs
 *
 * @param boolean $asArray return result as array instead of comma-separated list of IDs
 * @return array|string
 */
public function getAllChildren($asArray = false, $categoryId = false)
{
    if ($this->_category) {
        return $this->_category->getAllChildren($asArray);
    } else {
        return $this->getCategory($categoryId)->getAllChildren($asArray);
    }
}

public function getProductCollection($category_id_array)
{
    $collection = $this->_productCollectionFactory->create();
    $collection->addAttributeToSelect('*');
    $collection->addCategoriesFilter(['in' => $category_id_array]);
    $collection->addAttributeToFilter('visibility', \Magento\Catalog\Model\Product\Visibility::VISIBILITY_BOTH);
    $collection->addAttributeToFilter('status',\Magento\Catalog\Model\Product\Attribute\Source\Status::STATUS_ENABLED);
    $collection->setPageSize(9); // fetching only 9 products
    return $collection;
}

In phtml:

<?php
    $category_id_array = $this->getAllChildren(true,$this->getCurrentCategory()->getEntity_id());
    foreach ($block->getProductCollection($category_id_array) as $product) {
        var_dump($product->getData());
    }
?>

and it works in any category.

1
  • I don't know why it worked but only this worked for me after spending 2 days to see the list of the products on the category page.? any particular idea why the products are not displayed on the category page? Commented Nov 18, 2020 at 9:57
4

You can try the following code to resolve your query:

$objectManager = \Magento\Framework\App\ObjectManager::getInstance(); 
$cateinstance = $objectManager->create('Magento\Catalog\Model\CategoryFactory');
$cateid = '14';
$allcategoryproduct = $cateinstance->create()->load($cateid)->getProductCollection()->addAttributeToSelect('*');
1
  • 1
    You should never use \Magento\Framework\App\ObjectManager::getInstance()
    – Riccardo
    Commented Aug 22, 2020 at 12:06

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.