Reading list Switch to dark mode

    Get All Category Ids from Product Collection in magento2

    Updated 26 March 2024

    Get All Category IDs from Product Collection in Magento 2

    Today I will explain how you can retrieve all category IDs for every product from the product collection in Magento 2 in this article.

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

    After that, we will call the addCategoryIds() function from the collection, which will add the ‘category_ids’ array to the collection for every product which will contain all category IDs associated with 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
            foreach ($collection as $product) {
                print_r($product->getCategoryIds());
    
            }
        }
    }

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

    Searching for an experienced
    Magento Company ?
    Find out More

    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 the plugin you will get the category IDs with the product collection for sure. If you print the collection you will find an array with the 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 optimized way. Try this and if you have any queries then just comment below 🙂

    . . .

    Leave a Comment

    Your email address will not be published. Required fields are marked*


    Be the first to comment.

    Back to Top

    Message Sent!

    If you have more details or questions, you can reply to the received confirmation email.

    Back to Home