0

I am using following function to get product collection from a category with it's id.

public function getProductCollection($categoryId)
{
    $category = $this->_categoryFactory->create()->load($categoryId);
    $collection = $this->_productCollectionFactory->create();
    $collection->addAttributeToSelect('*');
    $collection->addCategoryFilter($category);
    $collection->addAttributeToFilter('visibility', \Magento\Catalog\Model\Product\Visibility::VISIBILITY_BOTH);
    $collection->addAttributeToFilter('status',\Magento\Catalog\Model\Product\Attribute\Source\Status::STATUS_ENABLED);
    return $collection;
}

This returns all the products in the category and products in subcatgories. I've enabled anchor for the category. I have found this solution for magento 1 which suggests to disable anchor for the category. But I need it be enabled so as to implement layered navigation.

Any idea on how we can get products only in the category excluding those in subcategories?

2 Answers 2

3

This is how is_anchor works in Magento. I had problems understanding the reason also. I still do, but I don't care anymore.
is_anchor, as you already stated, serves 2 purposes.

  • to include the subcategory products in the main category list,
  • to display the layered nav.

But I think you can trick Magento into thinking the category is not marked as anchor when retrieving the products.

Try something like this (not sure if it works but it's cheap to test).

public function getProductCollection($categoryId)
{
    $category = $this->_categoryFactory->create()->load($categoryId);
    $collection = $this->_productCollectionFactory->create();
    $collection->addAttributeToSelect('*');
    //remember if the category is marked as anchor
    $anchorFlag = $category->getIsAnchor();
    //tell magento that the category is not anchor
    $category->setIsAnchor(false);
    //apply the category filter. Magento should see the category as non anchor
    $collection->addCategoryFilter($category);
    //set back the anchor flag not to screw things up since objects are passed by reference
    $category->setIsAnchor($anchorFlag);
    $collection->addAttributeToFilter('visibility', \Magento\Catalog\Model\Product\Visibility::VISIBILITY_BOTH);
    $collection->addAttributeToFilter('status',\Magento\Catalog\Model\Product\Attribute\Source\Status::STATUS_ENABLED);
    return $collection;
}
1
  • is first point working for you when you setting is_anchor to 1 i.e. to include the subcategory products in the main category list. Commented Dec 26, 2018 at 14:27
2

Use following code it will return only products that assign in particular category.

$allCategoryId = 4;
$collection->addCategoriesFilter(array('in' => $allCategoryId));

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.