Magento 2 – Extending Product View Fails

blocksextendmagento2product

I would like to extend \Magento\Catalog\Block\Product\View but I get 404

<?php
namespace Vendor\Custom\Block;

use Magento\Catalog\Model\ProductFactory;
use Magento\Catalog\Block\Product\AbstractProduct;
use Magento\Framework\View\Element\Template;
use Magento\Catalog\Api\ProductRepositoryInterface;
use Magento\Catalog\Model\Product;

class MyProducts extends \Magento\Catalog\Block\Product\View
{
    protected $productFactory;

    protected  $_coreRegistry;
    /**
     * @param \Magento\Catalog\Block\Product\Context $context
     * @param array $data
     */
    public function __construct(
        \Magento\Catalog\Block\Product\Context $context,
        ProductFactory $productFactory
    ) {
        $this->productFactory = $productFactory;
        $this->_coreRegistry = $context->getRegistry();

        parent::__construct($context);
    }

}

?>

than I created in my module a di.xml which looks like

<?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 for="Magento\Catalog\Block\Product\View" type="Vendor\Custom\Block\MyProducts"/>
</config>

than I reference in product view as follows

<referenceBlock name="product.info.details">
            <block class="Vendor\Custom\Block\Variants" name="variants.tab" template="Vendor_Custom::variants.phtml" group="detailed_info">
                <arguments>
                    <argument translate="true" name="title" xsi:type="string">Product variations</argument>
                </arguments>
            </block>
        </referenceBlock>

Best Answer

Your constructor does not respect the parameters order of the parent class \Magento\Catalog\Block\Product\View, which looks like this:

public function __construct(
    \Magento\Catalog\Block\Product\Context $context,
    \Magento\Framework\Url\EncoderInterface $urlEncoder,
    \Magento\Framework\Json\EncoderInterface $jsonEncoder,
    \Magento\Framework\Stdlib\StringUtils $string,
    \Magento\Catalog\Helper\Product $productHelper,
    \Magento\Catalog\Model\ProductTypes\ConfigInterface $productTypeConfig,
    \Magento\Framework\Locale\FormatInterface $localeFormat,
    \Magento\Customer\Model\Session $customerSession,
    ProductRepositoryInterface $productRepository,
    \Magento\Framework\Pricing\PriceCurrencyInterface $priceCurrency,
    array $data = []
) {
    $this->_productHelper = $productHelper;
    $this->urlEncoder = $urlEncoder;
    $this->_jsonEncoder = $jsonEncoder;
    $this->productTypeConfig = $productTypeConfig;
    $this->string = $string;
    $this->_localeFormat = $localeFormat;
    $this->customerSession = $customerSession;
    $this->productRepository = $productRepository;
    $this->priceCurrency = $priceCurrency;
    parent::__construct(
        $context,
        $data
    );
}

So to fix your class, your constructor must look like this:

public function __construct(
    \Magento\Catalog\Block\Product\Context $context,
    \Magento\Framework\Url\EncoderInterface $urlEncoder,
    \Magento\Framework\Json\EncoderInterface $jsonEncoder,
    \Magento\Framework\Stdlib\StringUtils $string,
    \Magento\Catalog\Helper\Product $productHelper,
    \Magento\Catalog\Model\ProductTypes\ConfigInterface $productTypeConfig,
    \Magento\Framework\Locale\FormatInterface $localeFormat,
    \Magento\Customer\Model\Session $customerSession,
    ProductRepositoryInterface $productRepository,
    \Magento\Framework\Pricing\PriceCurrencyInterface $priceCurrency,
    ProductFactory $productFactory
    array $data = []
) {
    $this->productFactory = $productFactory;
    $this->_coreRegistry = $context->getRegistry();
    parent::__construct(
        $context,
        $urlEncoder,
        $jsonEncoder,
        $string,
        $productHelper,
        $productTypeConfig,
        $localeFormat,
        $customerSession,
        $productRepository,
        $priceCurrency,
        $data
    );
}
Related Topic