How to override non-public method in Magento2?

How_to_override_non-public_method_in_Magento2?

How to override a non-public method in Magento2?

Hey Everyone, This is MO Here we are going to explain how to override non-public methods in Magento 2. We can achieve this in two ways.

  • Event observers
  • Preferences

Events and observers


    Events and observers are used to carry out tasks on the data. They are an ideal way to extend Magento functionality.

    To use the Magento 2 Events and observers in your module you need to register events and observers in your events.xml which has to be placed in /etc/[area]/events.xml


Example: /etc/adminhtml/events.xml


<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:noNamespaceSchemaLocation="urn:magento:framework:Event/etc/events.xsd">
    <event name="catalog_product_save_before">
        <observer name="catalog_product_price_change_on_product_save"
                  instance="Mo\Tutorial\Observer\SetComputedProductPrice"/>
    </event>
</config>


Now we need to write the Observer for the Event


<?php

namespace Mo\Tutorial\Observer;

use Magento\Framework\Event\ObserverInterface;

class SetComputedProductPrice implements ObserverInterface
{

    public function execute(\Magento\Framework\Event\Observer $observer)
    {
        // Observer execution code...
    }
}
?>


Can we create a custom Event?

Yes, we can create custom Events in Magento 2. The following example shows you how

to dispatch an event with and without an array of data.

<?php
namespace Mo\Tutorial\Model;

use Magento\Framework\Event\ManagerInterface as EventManager;

class MoTutotial
{
    /**
     * @var EventManager
     */
    private $eventManager;

    /*
     * @param \Magento\Framework\Event\ManagerInterface as EventManager
     */
    public function __construct(EventManager $eventManager)
    {
        $this->eventManager = $eventManager;
    }

    public function sample()
    {
        $eventData = null;
        // Code...
        $this->eventManager->dispatch('mo_tutotial_event_before');
        // More code that sets $eventData...
        $this->eventManager->dispatch('mo_tutotial_event_after', ['eventData' => $eventData]);
    }
}

?>

    Custom events can be dispatched by simply passing a unique event name to the

event manager when you call the dispatch function.

    Your unique event name is referenced in your module’s events.xml file where you

specify which observers will react to that event.


Below is an example of how to assign observers to watch certain events:

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:noNamespaceSchemaLocation="urn:magento:framework:Event/etc/events.xsd">
    <event name="mo_tutotial_event_before">
        <observer name="moBeforeObserver" instance="Mo\Tutorial\Observer\MoBeforeObserver"/>
    </event>
    <event name="mo_tutotial_event_after">
        <observer name="moAfterObserver" instance=" Mo\Tutorial\Observer\MoAfterObserver"/>
    </event>
</config>

    One of the powerful features of observers is that they can use parameters passed into the

event when it was dispatched. 


Below is an example of an observer obtaining data and passing in when the event was

dispatched.

<?php

namespace Mo\Tutorial\Observer\Observer;

use Magento\Framework\Event\ObserverInterface;

class MoBeforeObserver implements ObserverInterface
{
    public function __construct()
    {
        // Observer initialization code...
        // You can use dependency injection to get any class this observer may need.
    }

    public function execute(\Magento\Framework\Event\Observer $observer)
    {
        $eventData = $observer->getData('eventData');
        // Observer execution code...
    }
}

?>
<?php
namespace Mo\Tutorial\Observer;

use Magento\Framework\Event\ObserverInterface;

class MoAfterObserver implements ObserverInterface
{
    public function __construct()
    {
        // Observer initialization code...
        // You can use dependency injection to get any class this observer may need.
    }

    public function execute(\Magento\Framework\Event\Observer $observer)
    {
        $eventData = $observer->getData('eventData');
        // Additional observer execution code...
    }
}

?>

Disabling an observer.

    Existing observers can be disabled if you do not want to run them. It is a good practice

to disable the observer, which can change its logic rather than override it. 

    Below is an example of how to disable the previously created observer.

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:noNamespaceSchemaLocation="urn:magento:framework:Event/etc/events.xsd">
    <event name="mo_tutotial_event_before">
        <observer name="moBeforeObserver" disabled="true"/>
    </event>
</config>

Event observers should not be used to modify data, If you want to modify, make use of

plugins. 

    Plugins are designed to modify the data flow in and out of the method. They wrap

and control the data flow. But using a plugin we can change only public methods. Now, if

the scenario is to modify any non-public methods, we need to go for preference.


Preference


    Using preference is recommended only when you need to modify any non-public

methods. 

    Preference is called a “class rewrite” in Magento1. Whenever the target code is called

our code is given instead of the target code.

To use a preference the preference needs to be registered in the di.xml

<?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="Mo\Tutorial\Model\TargetCode" type="Mo\Tutorial\Model\OurCode"/>
</config>

Create a class TargetCode.

<?php

namespace Mo\Tutorial\Model;


class TargetCode

{

    protected function sample()

    {

// your business logic

    }

}

?>                   

Once the preference is written in di.xml then we can write our class.

<?php

namespace Mo\Tutorial\Model;

Class OurCode extends \Mo\Tutorial\Model\TargetCode
{ Protected function sample() { // your business logic } } ?>

Use of Preference is not recommended but use it where you can’t neither plugins nor
events and observers.

If you are overriding Magento 2 core method your choice should be plugins, if not go for
events and observers, Atlast opt for preference.
(Keep their limitations in mind while using them) .

Check out our blog Magento 2 Interview questions to get some idea about Magento 2
Interview.

Thank you for reading. Are you fascinated to know more about Magento,
What are you waiting for? Check out the other blogs in the Magento section and
follow us through Youtube and Instagram to know more about us.

Post a Comment

0 Comments