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.
events and observers, Atlast opt for preference.
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.
0 Comments