0

This might feel a lengthy question but actually it is not big. I have just added some functions that I followed to try finding the actual code responsible for loading the product collection on category pages.

I am trying to look for the code that is responsible for fetching the products on category pages. These are the steps that I have followed.

  1. Checked the list.phtml file that displays the HTML for category pages. There I found the following code. File path for list.phtml vendor/magento/module-catalog/view/frontend/templates/product/list.phtml

enter image description here

  1. Then I went to the following block "@var $block \Magento\Catalog\Block\Product\ListProduct" and checked the getLoadedProductCollection function. This function took me to the following function "initializeProductCollection". Content of initializeProductCollection function.

    private function initializeProductCollection()
     {
     $layer = $this->getLayer();
     /* @var $layer Layer */
     if ($this->getShowRootCategory()) {
         $this->setCategoryId($this->_storeManager->getStore()->getRootCategoryId());
     }
    
     // if this is a product view page
     if ($this->_coreRegistry->registry('product')) {
         // get collection of categories this product is associated with
         $categories = $this->_coreRegistry->registry('product')
             ->getCategoryCollection()->setPage(1, 1)
             ->load();
         // if the product is associated with any category
         if ($categories->count()) {
             // show products from this category
             $this->setCategoryId($categories->getIterator()->current()->getId());
         }
     }
    
     $origCategory = null;
     if ($this->getCategoryId()) {
         try {
             $category = $this->categoryRepository->get($this->getCategoryId());
    
         } catch (NoSuchEntityException $e) {
             $category = null;
         }
    
         if ($category) {
             $origCategory = $layer->getCurrentCategory();
             $layer->setCurrentCategory($category);
         }
     }
     $collection = $layer->getProductCollection();
     $this->prepareSortableFieldsByCategory($layer->getCurrentCategory());
    
     if ($origCategory) {
         $layer->setCurrentCategory($origCategory);
     }
    
     $this->_eventManager->dispatch(
         'catalog_block_product_list_collection',
         ['collection' => $collection]
     );
    
      return $collection;
     }
    

This function has the following line that is loading the product collection.

$collection = $layer->getProductCollection();
  1. I looked and found out that $layer is calling get function of the following class - Magento\Catalog\Model\Layer\Resolver

This is the content of the get function

/**
     * Get current Catalog Layer
     *
     * @return \Magento\Catalog\Model\Layer
     */
    public function get()
    {
        if (!isset($this->layer)) {
            $this->layer = $this->objectManager->create($this-layersPool[self::CATALOG_LAYER_CATEGORY]);
    }
    
    return $this->layer;
}

If you see this function then it is creating this class Magento\Catalog\Model\Layer\Category

  1. So I went to this class but did not found anything but it has a parent class

     class Category extends \Magento\Catalog\Model\Layer
    
  2. Now I went to the parent class (\Magento\Catalog\Model\Layer) and found the following function

    public function getProductCollection()
     {
         if (isset($this->_productCollections[$this->getCurrentCategory()->getId()])) {
             $collection = $this->_productCollections[$this->getCurrentCategory()->getId()];
         } else {
             $collection = $this->collectionProvider->getCollection($this->getCurrentCategory());
             $this->prepareProductCollection($collection);
             $this->_productCollections[$this->getCurrentCategory()->getId()] = $collection;
         }
    
         return $collection;
     }
    
  3. There I saw collection is called in the following line.

     $collection = $this->collectionProvider->getCollection($this->getCurrentCategory());
    

I found out that $this->collectionProvider has following value assigned.

    $this->collectionProvider = $context->getCollectionProvider();

    And $context is this, \Magento\Catalog\Model\Layer\ContextInterface $context,
  1. So now I went to the Magento\Catalog\Model\Layer\ContextInterface class to find the getCollection function that I saw in this line: $collection = $this->collectionProvider->getCollection($this->getCurrentCategory());

  2. Now ContextInterface class has only the definition for this function and not the entire code

enter image description here

  1. But I found out that it is returning @return ItemCollectionProviderInterface so I went to this class and it has the following code.

enter image description here

  1. Here also we have the definition for getCollection function and not the entire code. But then again this function is returning @return \Magento\Catalog\Model\ResourceModel\Product\Collection

  2. So at last I reached to the Resource Model Class but again in this class I did not find getCollection function.

  3. I know ResourceModel are used by Magento for database related things. But here I could not find any code that is actually returning the products collection based on the category.

Could someone help me in understanding this and let me know how and where is the code that is responsible for fetching the products on category pages. I am really stuck into this and do not where to proceed now from here. Some guidance is really appreciated.

Update:

According to @Grazitti Dev The setCollection function is using the AbstractCollection which is coming from the magento_eav module and this module performs a query for products file located in vendor\magento\module-eav\Model\Entity\Collection\AbstractCollection.php.

Thank you for this suggestion. But could you help me in locating the function where the query is actually being made.

Actually I need to add my logic during this query so that the products are fetched according to my condition. I do not want to add my logic after the products are already fetched.

The solution that you suggested that I should apply, If I want to customize the product data. I think this will not work.

Because this will allow me to add my logic after the data is already fetched. But I need to add my logic while fetching the data and products should be fetched according to my condition.

Please guide me into this.

1 Answer 1

0

The Product Data is coming on the category page using the setCollection function which is located in the vendor\magento\module-catalog\Block\Product\ListProduct.php file.

The setCollection function is using the AbstractCollection which is coming from the magento_eav module and this module performs a query for products file located in vendor\magento\module-eav\Model\Entity\Collection\AbstractCollection.php.

If you want to customize the product data, then you need to create your plugin in which you can override this block (ListProduct.php).

Here are the steps to override : YourVendor/Module/etc/di.xml

<?xml version="1.0"?>
    <!--
    /**
     * Copyright © Magento, Inc. All rights reserved.
     * See COPYING.txt for license details.
     */
    -->
    <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
        <type name="Magento\Catalog\Block\Product\ListProduct">
            <plugin name="block-product-list" type="YourVendor\Module\Plugin\ListProduct" sortOrder="10" />
        </type>
    </config>

Then you can create the Plugin folder in below path : YourVendor/Module/Plugin/ListProduct.php

<?php
namespace YourVendor\Module\Plugin;

class ListProduct {

    public function afterGetProductDetailsHtml(
        \Magento\Catalog\Block\Product\ListProduct $subject,
        $result,
        \Magento\Catalog\Model\Product $product
    ) {
            // Add your custom code here
        return $result.$product->getName();
    }
}

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.