Magento 2 Plugin - Interceptor
Magento 2 Plugin is a technical plugin for your better writing code. Interception Plugin is referred to a little magento 2 extension that allows editing the behavior of any public class or method by intercepting a function call and running code either before or after or around the function call. By using this Magento 2 Plugin Interception, you can modify the behavior of a class while there is no need to change the class directly.
Table of contents
- Benefits of Magento 2 Plugin
- Magento 2 plugin’s restriction
- Guide for creating Magento 2 new plugin
- Set priority for plugins
- Magento 2 plugin example
Maybe you still think the observers can help you do that fluently but some differences need to be pointed out. Particularly, not only create functions of a class using dependency injection but Interception plugin can also be confirmed with a sortOrder, that allows checking the chain and order on which plugins run. That is the reason why this plugin doesn’t make the class change and doesn’t have any conflict with one another
Benefits of Magento 2 Plugin
For a module developer as you, Magento 2 Interception plugin allows:
- Forwarding any method call that is used on an object manager controlled object and taken programmatic action
- Modifying the return value of any method call that is used on an object manager controlled object
- Modifying the arguments of any method call that is used on an object manager controlled object
- Proceeding similarly when other modules are in progress of the same method in the same or predictable way.
If you have never had any experience in this way to create a system, it is not strange when you get confused with performance characteristics. But coming with the Mageplaza developer team who is confident in expert knowledge to know which software design patterns should be applied for this work. In this topic, maybe few of interceptor pattern will be given, so if you need to get more information or any problem not included in the scope of this post, please contact us.
Magento 2 plugin’s restriction
What options Magento 2 Interception plugin doesn’t work with?
- Objects that are instantiated before
Magento\Framework\Interception
is bootstrapped - Final methods
- Final classes
- Any class that contains at least one final public method
- Non-public methods
- Class methods (such as static methods)
__construct
- Virtual types
Guide for creating Magento 2 new plugin
Declaring a plugin in Magento 2
When setting up a new plugin for a class object, it will be defined in the di.xml
file at app/code/{namespace}/{module}/etc/di.xml
.
<config>
<type name="{ObservedType}">
<plugin name="{pluginName}" type="{PluginClassName}" sortOrder="1" disabled="false"/>
</type>
</config>
Explainations
Required options
type name
: Enter name of a class or interface that needs to be followed.plugin name
: An arbitrary plugin name that identifies a plugin. Also used to merge the configurations for the plugin.plugin type
: Fill the name of a plugin’s class or its virtual type. You can refer the following naming convention for this field:\Vendor\Module\Plugin\<ModelName>Plugin
.
Optional options
plugin sortOrder
: Set order when the plugin calls the other same methods in the process.plugin disabled
: That allows you enable or disable a plugin quickly. As the default configuration, the chosen value isfalse
. Use this property to disable core or third-party plugins in yourdi.xml
file.
As the following example, we will edit app\code\Mageplaza\HelloWorld\etc\di.xml
, you need to insert the snippet:
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../lib/internal/Magento/Framework/ObjectManager/etc/config.xsd">
<type name="Mageplaza\HelloWorld\Controller\Index\Example">
<plugin name="Mageplaza_HelloWorld_Plugin" type="Mageplaza\HelloWorld\Plugin\ExamplePlugin" sortOrder="10" disabled="false" />
</type>
</config>
For example, the following code define type name, we created Example.php
file at app/code/Mageplaza/HelloWorld/Controller/Index/
Contents would be:
<?php
namespace Mageplaza\HelloWorld\Controller\Index;
class Example extends \Magento\Framework\App\Action\Action
{
protected $title;
public function execute()
{
echo $this->setTitle('Welcome');
echo $this->getTitle();
}
public function setTitle($title)
{
return $this->title = $title;
}
public function getTitle()
{
return $this->title;
}
}
With plugin name, we created Example.php
file at app/code/Mageplaza/HelloWorld/Plugin/
Contents would be:
<?php
namespace Mageplaza\HelloWorld\Plugin;
class ExamplePlugin{
}
Defining a plugin in Magento 2
A plugin is a great way to expand or edit a public method’s behavior by using code before, after or around method.
First of all, please get an object that provides permission to all public methods of the observed method’s class.
3 methods in Plugin
before
-beforeDispatch()
around
-aroundDispatch()
after
-afterDispatch()
Before methods
Before methods are the first methods to run in an observed method, and these methods must have the same name to the observed one’s name while the prefix label is before
.
To apply the before methods for modifying the arguments of an observed method, you can return a modified argument. If there are multiple arguments, the returning will be carried out according to a range of those arguments. If the returning is invalid, that means the arguments for the observed method should not be modified.
<?php
namespace Mageplaza\HelloWorld\Plugin;
class ExamplePlugin
{
public function beforeSetTitle(\Mageplaza\HelloWorld\Controller\Index\Example $subject, $title)
{
$title = $title . " to ";
echo __METHOD__ . "</br>";
return [$title];
}
}
After methods
After methods start running right after the observed method is finished, and these methods must have the same name to the observed one’s name while the prefix label is “after”.
After methods take a responsibility of editing the results of an observed method in the correct way and being required to have a return value.
<?php
namespace Mageplaza\HelloWorld\Plugin;
class ExamplePlugin
{
public function afterGetTitle(\Mageplaza\HelloWorld\Controller\Index\Example $subject, $result)
{
echo __METHOD__ . "</br>";
return '<h1>'. $result . 'Mageplaza.com' .'</h1>';
}
}
Around methods
Around methods allows the code to run before and after the observed method, so you can override a method. These methods must have the same name to the observed one’s name while the prefix label is “around”.
Before the arrange of the original method’s argument, a callable
from around methods will be called to the next method in the chain, that means the next plugin or the observed function is also called.
Note: In case the callable
is not declared, the calling to neither the next plugin nor the original method is achieved.
<?php
namespace Mageplaza\HelloWorld\Plugin;
class ExamplePlugin
{
public function aroundGetTitle(\Mageplaza\HelloWorld\Controller\Index\Example $subject, callable $proceed)
{
echo __METHOD__ . " - Before proceed() </br>";
$result = $proceed();
echo __METHOD__ . " - After proceed() </br>";
return $result;
}
}
Check the result
All content of ExamplePlugin.php
<?php
namespace Mageplaza\HelloWorld\Plugin;
class ExamplePlugin
{
public function beforeSetTitle(\Mageplaza\HelloWorld\Controller\Index\Example $subject, $title)
{
$title = $title . " to ";
echo __METHOD__ . "</br>";
return [$title];
}
public function afterGetTitle(\Mageplaza\HelloWorld\Controller\Index\Example $subject, $result)
{
echo __METHOD__ . "</br>";
return '<h1>'. $result . 'Mageplaza.com' .'</h1>';
}
public function aroundGetTitle(\Mageplaza\HelloWorld\Controller\Index\Example $subject, callable $proceed)
{
echo __METHOD__ . " - Before proceed() </br>";
$result = $proceed();
echo __METHOD__ . " - After proceed() </br>";
return $result;
}
}
After this, please clear the cache and check the result. It will show like this
If your plugin is called by a method that matches with arguments, it must also match with them and simultaneously, you need to follow them carefully. During the process, please pay attention to the method’s original signature as well as the default parameters and the kind of suggestions.
For example, applying the below code to identify a parameter of type SomeType which is nullable
:
<?php
namespace Mageplaza\HelloWorld\Model;
class MyUtility
{
public function save(SomeType $obj = null)
{
//do something
}
}
If you wrapped this method with a plugin like below:
<?php
namespace Mageplaza\HelloWorld\Plugin;
class MyUtilityPlugin
{
public function aroundSave(\Mageplaza\HelloWorld\Model\MyUtility $subject, \callable $proceed, SomeType $obj)
{
//do something
}
}
Note: Missing = Null
If you call the method together with null, PHP would make a fatal error because your plugin null is not allowed in your plugin. Besides, it is important to follow the arguments from the plugin that is called by the method. But if not concern the arguments, please use the variadics and argument unpacking to complete this:
<?php
namespace Mageplaza\HelloWorld\Plugin;
class MyUtilityPlugin
{
public function aroundSave(\Mageplaza\HelloWorld\Model\MyUtility $subject, \callable $proceed, ...$args)
{
//do something
$proceed(...$args);
}
}
Set priority for plugins
sortOrder
option allow placing the plugins which are observing the same method in a queue. When before, after, or around methods start calling, the plugins are applied one by one.
Magento 2 plugin example
Visit https://github.com/mageplaza/magento2-samples/tree/master/sample-module-interception
0 comments:
Post a Comment
Thanks