Get All Category Ids from Product Collection in magento2

Get All Category Ids from Product Collection in magento2

Get All Category Ids from Product Collection in magento 2

Today I am going to explain that how you can retrieve all category Ids for every product from product collection in magento 2 in this article.

So, at first we will get collection of product with filter some product ids. You can write the code anywhere according to your requirement, and can apply any filter to it. I have written the code in module’s helper file.

And after that we will call addCategoryIds() function from the collection, which will adds ‘category_ids’ array to the collection for every product which will contain all category Ids associated to that product. Look at the code below:

 

<?php
namespace Company\Module\Helper;

use Magento\Catalog\Model\ResourceModel\Category\CollectionFactory;

class Data extends \Magento\Framework\App\Helper\AbstractHelper
{
    /**
     * @var \Magento\Catalog\Model\ResourceModel\Product\CollectionFactory
     */
    private $productCollection;

    public function __construct(
        \Magento\Catalog\Model\ResourceModel\Product\CollectionFactory $productCollection
    ) {
        parent::__construct($context);
        $this->productCollection = $productCollection;
    }

    public function getProductCollection()
    {
        $productIds = [1,2,3,4];
        $collection = $this->productCollection->create()
        ->addAttributeToSelect('*')
        ->addStoreFilter()
        ->addFieldToFilter(
            'entity_id',
            ['in' => $productIds]
        )
        ->addCategoryIds(); // the main function to get all category ids
    }
}

 

By printing above collection data, you must be getting ‘category_ids’ as key with array of category ids. But if in case you are not getting ‘category_ids’ value from the above collection then you can create after plugin for the function addCategoryIds() as below:

In your module’s di.xml file write the following code :

 

<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    <type name="Magento\Catalog\Model\ResourceModel\Product\Collection">
        <plugin name="Company_Module::productcollection" type="Company\Module\Model\Plugin\Productcollection" sortOrder="1" />
    </type>
</config>

 

Now create a file Productcollection.php for the plugin under the path as mentioned above, i.e. Company\Module\Model\Plugin\ and write the below code in the file :

 

<?php
namespace Company\Module\Model\Plugin;

class Productcollection
{
    public function afterAddCategoryIds(
        \Magento\Catalog\Model\ResourceModel\Product\Collection $subject,
        $result
    ) {
        if ($subject->getFlag('category_ids_added')) {
            return $subject;
        }
        $ids = array_keys($subject->getItems());
        if (empty($ids)) {
            return $subject;
        }

        $select = $subject->getConnection()->select();

        $select->from(
            $subject->getResource()->getTable('catalog_category_product'),
            ['product_id', 'category_id']
        );
        $select->where('product_id IN (?)', $ids);

        $data = $subject->getConnection()->fetchAll($select);

        $categoryIds = [];
        foreach ($data as $info) {
            if (isset($categoryIds[$info['product_id']])) {
                $categoryIds[$info['product_id']][] = $info['category_id'];
            } else {
                $categoryIds[$info['product_id']] = [$info['category_id']];
            }
        }

        foreach ($subject->getItems() as $item) {
            $productId = $item->getId();
            if (isset($categoryIds[$productId])) {
                $item->setCategoryIds($categoryIds[$productId]);
            } else {
                $item->setCategoryIds([]);
            }
        }

        $subject->setFlag('category_ids_added', true);
        return $result;
    }
}

 

NOTE : By using plugin you will get the category ids with the product collection for sure. If you print the collection you will find there an array with key ‘category_ids’ which will contain all category ids associated with that product.

 

So by using this method, i.e. addCategoryIds(), you will not have to use any join or loop to get all category Ids with product collection.

Hope this blog will help you to develop functionality in a better and optimised way. Try this and if you have any query then just comment below 🙂