How to Overriding classes in Magento 2?

Overriding Classes in Magento 2

There are many ways to override methods and classes. In most situations, using a class is more preferable. Rewriting a new class can create conflict. For this, plugins are introduced. All the classes are defined by their interfaces and configured by di.xml files. There’s an abstraction-implementation mapping implemented when the constructor signature of a class requests an object by its interface. That means that interfaces should be used, where available, and the mapping will tell which class should be initiated.

Below can be the paths for module di.xml files inside VendorName/ModuleName:

/etc/di.xml
/etc/<area>/di.xml

Plugins:

Plugins can be configured in this di.xml and they are called before, after and around the methods are being below is example of di.xml file code

<config>
    <type name="Magento\Catalog\Api\Data\ProductInterface">
        <plugin name="bay20_test_catalog_product" type="Bay20\Test\Plugin\Model\Product" />
    </type>
</config>
  • Before Method

Before running the plugin properly to an observed method and has to return the same number of modified arguments in an array. If the method does not change the argument for the observed method, it should return a null value.

Below is an example of a before method modifying the $price argument before passing it on to the observed setPrice method.

<?php
namespace Bay20\Test\Plugin\Model;
 
class Product
{
    public function beforeSetPrice(\Magento\Catalog\Model\Product $subject, $price)
    {
        $price += 10;
        return [$price];
    }
}

  • After Method

After method is executed only the original method is called. Next to a class object the method accepts one more argument and that’s the result that also must return. Method that’s being extended has to have the same name with prefix “after”.

Below is an example of an after method modifying the return value $result of an observed methods calls.

<?php
namespace Bay20\Test\Plugin\Model;
 
class Product
{
    public function afterGetName(\Magento\Catalog\Model\Product $subject, $result)
    {
        $result .= ' Suffix';
        return $result;
    }
}

  • Around Method

When you call around method, original method is wrapped and allow code execution before and after the original method call. Next to a class object, the method that accepts another argument receives is callable which allows other plugins call in the chain. Method that’s being extended has to have the same name with prefix “around”.

<?php
namespace Bay20\Test\Plugin\Model;
 
class Product
{
    public function aroundSave(\Magento\Catalog\Model\Product $subject, \callable $proceed)
    {
        // before save
        $result = $proceed();
        // after save
 
        return $result;
    }
}

Conclusion:

There’s more than one way of overriding classes and methods and choosing which one to use will depend on a situation you run into. While using a class preference as a way of overriding may look like the easiest way which will work in most situations, it’s the cause of many conflicts when different modules try to override the same classes and the same methods, which is why all the ways should be taken into consideration.

Please contact us at manish@bay20.com or call us at +91-8800519180 for any support related to Magento 2. You can also visit the Magento2 development page to check the services we offer.