Overloading a native magento2 class (Model, Block, Helper, Action ...)

Sometimes we want to modify the native behavior of magento2, we may be tempted to edit the files directly in the app/code/Magento module, but it MUST NOT be done because you will not be able to update your platform to new versions from magento2 after it. How to edit a magento2 class properly then?

Rewrite a native magento2 module

In this first part of the tutorial, we will see how to rewrite a class of the Model, more specifically, the Product class.

Step 1: Define the class used by the dependency injector

Edit your configuration file for dependency injection : /app/code/Pfay/Contacts/etc/di.xml and add a "preference" item to tell magento "take the class Pfay\Contacts\Model\Product instead of Magento\Catalog\Model\Product" :

<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    ...
    <preference for="Magento\Catalog\Model\Product" type="Pfay\Contacts\Model\Product" />
</config>

Step 2: Create the Rewritten class

Once we have defined magento to take this new class, we must create it. Create the file /app/code/Pfay/Contacts/Model/Product.php :

<?php
namespace Pfay\Contacts\Model;
use Magento\Cron\Exception;
use Magento\Framework\Model\AbstractModel;
class Product extends \Magento\Catalog\Model\Product
{
    /**
     * Get product name
     *
     * @return string
     * @codeCoverageIgnoreStart
     */
    public function getName()
    {
        return parent::getName().' motherfucker !!';
    }

}

Here we declare a new Product class as usual when creating a new model. Then we extend the native \Magento\Catalog\Model\Product class. In order not to lose the native behavior of the class and to be able to overload only what one needs. We will override the getName() function of the native model of magento, for this we retrieve the product name (via the native function present in the parent class) then we add "motherfucker !!" at the end. Then go on a product sheet and you should see the name of the product "mother fuckers !!" at the end. So it works perfectly well :)

Rewrite a magento2 block

To rewrite a block it is the same thing, we will create our "preference" in the di.xml and we will create the class concerned, here we will try to overload the block product view of magento (/app/code/Magento/Catalog/Block/Product/View.php). So we start by adding our new "preference", edit the file /app/code/Pfay/Contacts/etc/di.xml

<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\View" type="Pfay\Contacts\Block\Product\View" />
    
</config>

Then create the class:

<?php
namespace Pfay\Contacts\Block\Product;

class View extends \Magento\Catalog\Block\Product\View
{
    /**
     * Retrieve current product model
     *
     * @return \Magento\Catalog\Model\Product
     */
    public function getProduct()
    {
       die('test rewrite block product view');
    }
}

If you reload your page, you should see a blank page with "test rewrite block product view".

Rewrite a Helper in magento2

To rewrite a helper it is the same thing, we will still create our "preference" in the di.xml and we will still create the Helper class, here we will re-create the helper catalog data of magento (/app/code/Magento/Catalog/Helper/Data.php). As usual edit the /app/code/Pfay/Contacts/etc/di.xml to create a new preference :

<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    
    ...
    
    <preference for="Magento\Catalog\Helper\Data" type="Pfay\Contacts\Helper\Data" />
    
</config>

Then create the class /app/code/Pfay/Contacts/Helper/Data.php which is rewriting the getProduct() to put a die() in it.

<?php
namespace Pfay\Contacts\Helper;

class Data extends \Magento\Catalog\Helper\Data
{
    public function getProduct()
    {
        die('rewrite helper');
        return $this->_coreRegistry->registry('current_product');
    }
}

If you reload your product page, you should see a blank page with "rewrite helper" (result of die() here).

Rewrite an Action in magento2

You want to change the native code of a magento2 action, such as displaying the shopping cart. To do so you might be tempted to directly modify the corresponding action in the app/code/Magento folder, but as you can imagine and as we said before...it's not a good idea. Indeed, the magento club's #1 rule: we do not talk about the magento club NEVER MODIFY THE MAGENTO CORE (app/code/Magento). So now that is said, we will be able to edit our di.xml and add the preference ... As for the other rewrites :)
So as usual now, edit the /app/code/Pfay/Contacts/etc/di.xml file to create the preference:

<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    
    ...
    
    <preference for="Magento\Checkout\Controller\Cart\Index" type="Pfay\Contacts\Controller\Cart\Index" />
    
</config>

Then create your class \Pfay\Contacts\Controller\Cart\Index as follows:

<?php
namespace Pfay\Contacts\Controller\Cart;

class Index extends \Magento\Checkout\Controller\Cart\Index
{
    public function execute()
    {
      die('test cart');
    }
}

And if you go to your cart, you see a blank page "test cart". So it works;)
This is the end of this magento rewrites tutorial, you've seen how to rewrite / override a helper, block, model and action under magento2 .
If this does not work for you, you can download the code at the bottom of this tutorial to compare it with yours.
Available documents for this article :
Books that can help you :
  • Livre Magento 2 Developer's Guide by Branko
  • Livre Mastering Magento2 Second Edition
  • Livre Magento 2 Cookbook
Questions about this lesson
No questions for this lesson. Be the first !

You must be logged in to ask for help on a lesson.