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

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 is false. Use this property to disable core or third-party plugins in your di.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

magento 2 plugin

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

Related Topics

Enjoyed the tutorial? Spread it to your friends!

magento-2-tutorial
magento-2-plugin
magento-2-interceptor

Jacker Ngo
Jacker Ngo

Magento Developer who is passionate about development and love technology. Jacker’s story

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.2.x, 2.3.x, 2.4.x