Magento 2 Override ListProduct.php Block File
-
14-04-2021 - |
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
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:
- 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;
}
}