I'm trying to extend a Block in Magento, the Magento\Catalog\Block\Product\ListProduct
block and Inject a dependency on it, but I've hit a wall and just get this error.
Fatal error: Uncaught TypeError: Argument 2 passed to Holy\Demo\Block\Product\ListProduct::__construct() must implement interface Magento\CatalogInventory\Api\StockStateInterface, instance of Magento\Framework\Data\Helper\PostHelper given, called in /var/www/html/generated/code/Holy/Demo/Block/Product/ListProduct/Interceptor.php on line 14 and defined in /var/www/html/app/code/Holy/Demo/Block/Product/ListProduct.php:14 Stack trace: #0 /var/www/html/generated/code/Holy/Demo/Block/Product/ListProduct/Interceptor.php(14): Holy\Demo\Block\Product\ListProduct->__construct(Object(Magento\Catalog\Block\Product\Context), Object(Magento\Framework\Data\Helper\PostHelper), Object(Magento\Catalog\Model\Layer\Resolver), Object(Magento\Catalog\Model\CategoryRepository\Interceptor), Object(Magento\Framework\Url\Helper\Data), Array) #1 /var/www/html/lib/internal/Magento/Framework/ObjectManager/Factory/AbstractFactory.php(111): Holy\Demo\Block\Product\ListProduct\Inte in /var/www/html/app/code/Holy/Demo/Block/Product/ListProduct.php on line 14
This is the di.xml of my module:
<?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="Holy\Demo\Block\Product\ListProduct" />
</config>
And this is my Block class:
<?php
namespace Holy\Demo\Block\Product;
/**
* Product list
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
*/
class ListProduct extends \Magento\Catalog\Block\Product\ListProduct
{
/**
* @param \Magento\CatalogInventory\Api\StockStateInterface $stockState
*/
public function __construct(
\Magento\Catalog\Block\Product\Context $context,
// \Magento\Backend\Block\Template\Context $context,
\Magento\CatalogInventory\Api\StockStateInterface $stockState,
array $data = []
)
{
$this->stockState = $stockState;
parent::__construct($context, $data);
}
public function getStockQty($product) {
// TODO: Don't use objectManager, Inject the \Magento\CatalogInventory\Api\StockStateInterface on the constructor of the block
// $_objectManager = \Magento\Framework\App\ObjectManager::getInstance();
// $_stockState = $_objectManager->get('\Magento\CatalogInventory\Api\StockStateInterface');
// return $_stockState->getStockQty($product->getId(), $product->getStore()->getWebsiteId());
return $this->stockState->getStockQty($product->getId(), $product->getStore()->getWebsiteId());
}
}
UPDATE
I was able to get it working by adding all of the parent class arguments from it's constructor to my constructor, but this does not seem like a good approach to me as if in a Magento update a new dependency is added to the parent class, won't that break my module?
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,
\Magento\CatalogInventory\Api\StockStateInterface $stockState,
array $data = []
)
{
$this->stockState = $stockState;
parent::__construct($context, $postDataHelper , $layerResolver, $categoryRepository, $urlHelper, $data);
}