Question

I am trying to override ListProduct.php file in my custom module,

Steps:

File: etc/frontend/di.xml

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    <preference for="Magento\Catalog\Block\Product\ListProduct" type="Vendor\Module\Block\Product\ListProduct" />
</config>

Vendor\Module\Block\Product\ListProduct.php Overrided File:-

    <?php
/**
 * Copyright © Magento, Inc. All rights reserved.
 * See COPYING.txt for license details.
 */

namespace Vendor\Module\Block\Product;

use Magento\Catalog\Api\CategoryRepositoryInterface;
use Magento\Catalog\Block\Product\ProductList\Toolbar;
use Magento\Catalog\Model\Category;
use Magento\Catalog\Model\Config;
use Magento\Catalog\Model\Layer;
use Magento\Catalog\Model\Layer\Resolver;
use Magento\Catalog\Model\Product;
use Magento\Catalog\Model\ResourceModel\Product\Collection;
use Magento\Catalog\Pricing\Price\FinalPrice;
use Magento\Eav\Model\Entity\Collection\AbstractCollection;
use Magento\Framework\App\ActionInterface;
use Magento\Framework\App\Config\Element;
use Magento\Framework\Data\Helper\PostHelper;
use Magento\Framework\DataObject\IdentityInterface;
use Magento\Framework\Exception\NoSuchEntityException;
use Magento\Framework\Pricing\Render;
use Magento\Framework\Url\Helper\Data;

class ListProduct extends \Magento\Catalog\Block\Product\ListProduct
{
    protected $_defaultToolbarBlock = Toolbar::class;

    protected $_productCollection;

    protected $_catalogLayer;

    protected $_postDataHelper;

    protected $urlHelper;

    protected $categoryRepository;

    private $logger;

    public function __construct(
        \Magento\Framework\App\Action\Context $context,
        PostHelper $postDataHelper,
        Resolver $layerResolver,
        CategoryRepositoryInterface $categoryRepository,
        Data $urlHelper,
        \Psr\Log\LoggerInterface $logger = null,
        array $data = []
    ) {
        parent::__construct(
            $context,
            $data,
            $layerResolver->get(),
            $postDataHelper,
            $categoryRepository,
            $urlHelper
        );
        $this->logger = $logger ?? $this->_objectManager->get(\Psr\Log\LoggerInterface::class);
    }

    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(current($categories->getIterator())->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();
        $collection->addAttributeToFilter('best_price', '1');

        $this->prepareSortableFieldsByCategory($layer->getCurrentCategory());

        if ($origCategory) {
            $layer->setCurrentCategory($origCategory);
        }

        $this->addToolbarBlock($collection);

        $this->_eventManager->dispatch(
            'catalog_block_product_list_collection',
            ['collection' => $collection]
        );

        return $collection;
    }
}
?>

Error:

Exception #0 (Magento\Framework\Exception\RuntimeException): Type Error occurred when creating object: Vendor\Module\Block\Product\ListProduct\Interceptor

Please guide me to fix this..

What I need: Basically I need to override initializeProductCollection function.

What I did: I had cleared cache, , Run di:compile command , Run Upgrade Command But not worked

Was it helpful?

Solution

Try this

Vender/Module/etc/di.xml

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../lib/internal/Magento/Framework/ObjectManager/etc/config.xsd">

         <preference type="Vender\Module\Block\Product\ListProduct" 
           for="Magento\Catalog\Block\Product\ListProduct"/>


</config>

Vender/Module/view/frontend/layout/catalog_category_view.xml

<?xml version="1.0"?>
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" layout="2columns-left" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
    <body>
        <referenceContainer name="content">
                 <referenceBlock name="category.products.list"  template="Vender_Module::product/listt.phtml">
                    <block class="Magento\Catalog\Block\Product\ListProduct" name="dummy" />
                 </referenceBlock>
        </referenceContainer>
    </body>
</page>

Vender/Module/Block/Product/ListProduct.php

<?php

namespace Vender\Module\Block\Product;

use Magento\Catalog\Model\Product;

class ListProduct extends \Magento\Catalog\Block\Product\ListProduct
{
    protected $_customerSession;
    protected $categoryFactory;

    /**
     * ListProduct constructor.
     * @param \Magento\Catalog\Block\Product\Context $context
     * @param \Magento\Framework\Data\Helper\PostHelper $postDataHelper
     * @param \Magento\Catalog\Model\Layer\Resolver $layerResolver
     * @param \Magento\Catalog\Api\CategoryRepositoryInterface $categoryRepository
     * @param \Magento\Framework\Url\Helper\Data $urlHelper
     * @param Helper $helper
     * @param array $data
     * @param \Magento\Customer\Model\Session $customerSession
     * @param \Magento\Catalog\Model\CategoryFactory $categoryFactory
     */
    public function __construct(
    \Magento\Catalog\Block\Product\Context $context,
    \Magento\Framework\Data\Helper\PostHelper $postDataHelper,
    \Magento\Catalog\Model\Layer\Resolver $layerResolver,
    \Magento\Catalog\Api\CategoryRepositoryInterface $categoryRepository,
    \Magento\Framework\Url\Helper\Data $urlHelper,
    array $data = [],
    \Magento\Customer\Model\Session $customerSession,
    \Magento\Catalog\Model\CategoryFactory $categoryFactory
    ) {
        $this->_customerSession = $customerSession;
        $this->categoryFactory = $categoryFactory;
        $this->_helper = $helper;
        parent::__construct(
            $context,
            $postDataHelper,
            $layerResolver,
            $categoryRepository,
            $urlHelper,
            $data
        );

    }

    public function yourFunction()
    {
        //your function
    }


}

and in your phtml file

Vender/Module/view/frontend/template/product/listt.phtml

<h1>Your Text here</h1>

OTHER TIPS

Try This:

  1. Step 1.

Please write below code in your module di.xml

app/code/Namespace/Modulename/etc/di.xml


    <preference type="Magento\Catalog\Block\Product\ListProduct" for="Namespace\Modulename\Block\Rewrite\Product\ListProduct"/>

Step 2:

Please override the ListProduct.php file.

A. Please create ListProduct.php this file in this path.

app/code/Namespace/Modulename/Block\Rewrite\Product\ListProduct.php

------ListProduct.php-------------

Please add below code in this path then you can override any function for the list page.

namespace Namespace\Modulename\Block\Rewrite\Product;

use Magento\Catalog\Api\CategoryRepositoryInterface; use Magento\Catalog\Block\Product\ProductList\Toolbar; use Magento\Catalog\Model\Category; use Magento\Catalog\Model\Config; use Magento\Catalog\Model\Layer; use Magento\Catalog\Model\Layer\Resolver; use Magento\Catalog\Model\Product; use Magento\Catalog\Model\ResourceModel\Product\Collection; use Magento\Catalog\Pricing\Price\FinalPrice; use Magento\Framework\App\ActionInterface; use Magento\Framework\App\Config\Element; use Magento\Framework\Data\Helper\PostHelper; use Magento\Framework\DataObject\IdentityInterface; use Magento\Framework\Exception\NoSuchEntityException; use Magento\Framework\Pricing\Render; use Magento\Framework\Url\Helper\Data;

class ListProduct extends \Magento\Catalog\Block\Product\ListProduct {

protected $_defaultToolbarBlock = Toolbar::class;

protected $_productCollection;

protected $_catalogLayer;

protected $_postDataHelper;

protected $urlHelper;

protected $categoryRepository;

private $logger;

public function __construct(
\Magento\Catalog\Block\Product\Context $context,
\Magento\Framework\Data\Helper\PostHelper $postDataHelper,
\Magento\Catalog\Model\Layer\Resolver $layerResolver,
\Magento\Catalog\Api\CategoryRepositoryInterface $categoryRepository,
\Magento\Framework\Url\Helper\Data $urlHelper,
array $data = [],
\Magento\Customer\Model\Session $customerSession,
\Magento\Catalog\Model\CategoryFactory $categoryFactory
) {
    $this->_customerSession = $customerSession;
    $this->categoryFactory = $categoryFactory;
    parent::__construct(
        $context,
        $postDataHelper,
        $layerResolver,
        $categoryRepository,
        $urlHelper,
        $data
    );

}

 /**
 * Retrieve loaded product collection
 *
 * The goal of this method is to choose whether the existing collection should be returned
 * or a new one should be initialized.
 *
 * It is not just a caching logic, but also is a real logical check
 * because there are two ways how collection may be stored inside the block:
 *   - Product collection may be passed externally by 'setCollection' method
 *   - Product collection may be requested internally from the current Catalog Layer.
 *
 * And this method will return collection anyway,
 * even when it did not pass externally and therefore isn't cached yet
 *
 * @return AbstractCollection
 */
protected function _getProductCollection()
{
    if ($this->_productCollection === null) {
        $this->_productCollection = $this->initializeProductCollection();
    }

    return $this->_productCollection;
}


/**
 * Retrieve loaded category collection
 *
 * @return AbstractCollection
 */
public function getLoadedProductCollection()
{
    return $this->_getProductCollection();
}

 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(current($categories->getIterator())->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;
}

}

Licensed under: CC-BY-SA with attribution
Not affiliated with magento.stackexchange
scroll top