2

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

  • extend the ListProduct.php from exact class... Look at my class it works perfectly for me – Asad Khan Jun 21 '19 at 13:00
  • @AsadKhan not worked... – temper Jun 24 '19 at 5:38
2

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>
| improve this answer | |
  • I already did this and it is not working, the difference in my code and your code is you had override list.phtml aswell, thankyou for giving me idea. – temper Jun 24 '19 at 4:45
  • the issue is you extends your class from \Magento\Catalog\Block\Product\AbstractProduct implements IdentityInterface while you need to extend it from \Magento\Catalog\Block\Product\ListProduct after that Inshallah it will work for you :) – Asad Khan Jun 24 '19 at 5:19
  • I had updated my question, can you please check once again? – temper Jun 24 '19 at 5:31
  • Please help me if you have idea how to resolve this issue. – temper Jun 24 '19 at 6:03
  • wait.... did you delete your generated folder?? – Asad Khan Jun 24 '19 at 6:04
0

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;
}

}

| improve this answer | |
  • after enabling elasticsearch its not working is there any way we can fix it – Pramod Jul 30 at 13:26

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.