Magento 2 Plugin - Interceptor
Magento 2 Plugin is a technical plugin that helps with better code writing. Interception Plugin is 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.
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, which 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 like you, Magento 2 Interception plugin allows:
- Forwarding any method call that is used on an object manager-controlled object and taking 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 creating a system in this way to, it is not strange when you get confused with performance characteristics. 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 a few interceptor patterns 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 does Magento 2 Interception plugin don’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>
Explanations
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 to 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 to 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 defines 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 the 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 as the observed one’s name while the prefix label is before
.
To apply the previous methods for modifying the arguments of an observed method, you can return a modified argument. If there are multiple arguments, the return will be carried out according to a range of those arguments. If the return 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 as the observed one’s name while the prefix label is “after”.
After methods take the 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 allow the code to run before and after the observed method, so you can override a method. These methods must have the same name as the observed one’s name while the prefix label is “around”.
Before the arrangement 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 them, and 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 will 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 concerned with 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
The sortOrder
option allows the plugins that are observing the same method to be placed 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
Related Topics
- How to Create Module in Magento 2
- How to Create Controller in Magento 2
- Magento 2 Routing
- Magento 2 Extensions
- How to use Plugin in Magento 2
-
[How to Override Classes in Magento 2 Using Plugin Unlocked](https://www.mageplaza.com/devdocs/override-classes-using-plugin-magento-2.html)
- How to create a simple Hello World module for Magento 2
- Magento 2 Block Template Ultimate Guides
- How to Create Module in Magento 2
- How to Create Controller in Magento 2
- How to create CRUD Models in Magento 2
- How to Create Magento 2 Block, Layout and Templates
- Configuration - System.xml
- How To Create Admin Menu In Magento 2
- Admin ACL
- Admin Grid
People also searched for
- magento 2 plugin
- magento 2 plugins interceptor
- magento 2 plugin not working
- magento 2 preference
- magento 2 interceptor
- magento plugin tutorial
- magento 2 preference vs plugin
- magento 2 plugin constructor
- magento plugin list
- how to use plugin in magento 2
- magento 2 after plugin
- magento 2 plugin example
- magento 2 plugins
- magento 2 create plugin
- magento 2 before plugin
- magento 2 around plugin
- before plugin magento 2
- around plugin magento 2
- after plugin magento 2
- magento 2 around plugin example
- magento 2 after plugin example
- magento 2 Before plugin example
- how to create plugin in magento 2
- what is plugin in magento 2
- magento 2 plugin tutorial
- magento 2 plugin after execute
- magento 2 plugin for controller
- magento 2 plugin sort order
- how to use plugin in magento 2
- magento 2 around plugin with parameters
- magento 2 plugin development
- magento 2 before plugin multiple arguments
- magento 2 plugin abstract class
- 2.3.x, 2.4.x