Magento – Block override in Magento2 not working

blocksdependency-injectionmagento2module

I'm working on a custom module for magento2. Trying to override the product view block so I can fetch data from an API and pass it into the view. Having read

  1. https://community.magento.com/t5/Programming-Questions/Overriding-a-block-in-Magento-2/m-p/6831#U6831
  2. Magento 2: Override Magento\Catalog\Block\Product\View Block
  3. DI & Extending a Block on Magento 2

I'm still unsuccessful… Here's what I have in my module (Moxune/Moxune):

Block/Product/View.php

<?php
namespace Moxune\Moxune\Block\Product;

use Magento\Framework\View\Element\Template;
use Magento\Catalog\Api\ProductRepositoryInterface;
use Magento\Catalog\Model\Product;
class View extends \Magento\Catalog\Block\Product\View
{
    protected function _toHtml()
    {
        $this->setModuleName($this->extractModuleName('Magento\Catalog\Block\Product\View'));
        return parent::_toHtml();
    }
}

etc/di.xml

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <preference for="Magento\Catalog\Block\Product\View" type="Moxune\Moxune\Block\Product\View" />
</config>

I then run

rm -rf var/cache var/di var/generation var/page_cache && ./bin/magento setup:di:compile

and navigate to a product detail page. I can tell the overridden block isn't getting called though, because I've changed the _toHtml() body to:

protected function _toHtml()
{
   die('wtf');
}

and also introduced syntax errors and the page continues to load fine. However, if I put a die statement in the _toHtml() of

var/generation/Magento/Catalog/Block/Product/View/Interceptor.php

that shows on the product detail page. So it seems the preference I'm configuring is having no effect?

FWIW – It seems the DI process is creating a new Interceptor based on the configured preference:

var/generation/Moxune/Moxune/Block/Product/View/Interceptor.php

What am I missing?

Best Answer

So I got something working... I discovered the DI configuration was mapping Magento\Catalog\Block\Product\View to Magento\Catalog\Block\Product\View\Interceptor which is not the generated interceptor I was expecting (Moxune\Moxune\Block\Product\View\Interceptor).

I'm not sure exactly why, but my Magento installation (v2.0.4) does not have a view/frontend/templates/product/view.phtml file, so my guess is the block I was trying to override isn't being used. I did find several other (seemingly more granular) template files and decided to shoot for a block that might correspond to one of those.

That said, I've

  1. Changed my module's di.xml file to

    <?xml version="1.0"?>
    <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
        <preference for="Magento\Catalog\Block\Product\View\Description"
            type="Moxune\Moxune\Block\Product\View\Description" />
    </config>
    
  2. Created the corresponding class

    namespace  Moxune\Moxune\Block\Product\View;
    
    use Magento\Framework\View\Element\Template;
    use Magento\Catalog\Api\ProductRepositoryInterface;
    use Magento\Catalog\Model\Product;
    
    class Description extends \Magento\Catalog\Block\Product\View\Description {
        protected function _toHtml() {   
            $this->setModuleName($this->extractModuleName('Magento\Catalog\Block\Product\View\Description'));
            return parent::_toHtml();
        }   
    }
    
  3. Recompiled the DI configuration

    rm -rf var/cache var/di var/generation var/page_cache ; ./bin/magento setup:di:compile
    

Now I seem to be getting into the _toHtml method of my overridden class!