Home / 
Blog / 
Magento 2 – create plugins
thumbnail

Magento 2 – create plugins

In this topic, we will create three types of plugins (interceptor). These methods help to change data before or after execute some method and we can change the whole body of the method. Plugins don’t work with :

  • final class
  • final methods
  • protected/private method
  • static methods
  • __constructor
  • virtual types
  • class which doesn’t have any interceptor

Notice: Creating the module tutorial is here.

STEP 1. Create di.xml to declare your plugin file

In this step, we will create a configuration file to declare where our plugin class is, and what class we want to “override”.

The file should have path like this pattern:

app/code/[your_namespace]/[your_module]/[area*]/etc/di.xml

In our case it’s:

app/code/PandaGroup/PluginExample/etc/frontend/di.xml

* area it’s optional. If you want to affect only on frontend add frontend area folder, if you want to affect only admin area – add adminhtml area. If you want global – add it in /etc folder.

The content looks like this:

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
   <type name="Magento\Catalog\Model\Product">
       <plugin name="pandagroup_pluginexample_procuct" type="PandaGroup\PluginExample\Plugin\Product" sortOrder="1" disabled=false/>
   </type>
</config>

Where:

  • type node – here we have to type the name of the class which we want to deal with. We’ve chosen Product, because we want to deal with getPrice() method. So in name property – type class what we want to deal with.
  • plugin – in this node we have to declare the name of our plugin class – best practice of name is [vendor]_[module_name]_[class/object name]. The second property ‘type’ – here you should pass class where you declare your plugin functions. Next one is sortOrder – this tells magento, which plugin should be executed first, second etc. The bigger the number the later these plugins will be executed. The last one property is disabled. If you want disable plugin – type here disabled=”true”.

STEP 2. Create a plugin class.

Ok, so now we have xml with configuration. Now let’s create a Plugin class. Make a Plugin folder in your module, and create a class with the name which you declared in di.xml. In our case it’s Product.

The file should have a path like this pattern:

app/code/[your_namespace]/[your_module]/Plugin/[name_of_plugin_class].php

In our case it’s:
app/code/PandaGroup/PluginExample/Plugin/Product.php

In this example, we will make plugins for function getPrice().

And now we have 3 types of plugins:

  • before – used to modify the input arguments of a method. To modify the function in this way, you have to create function like this example:

    – base function getPrice()
    – plugin function beforeGetPrice()

    So this function code will be like this:
<?php

  declare(strict_types=1);

  namespace PandaGroup\PluginExample\Plugin;

  class Product
  {
    public function beforeGetPrice(\Magento\Catalog\Model\Product $product, $price) : float
  {
    /...   
    return $price;
  }
  }
  • after – used to modify the output from a public method. In that case, you should create a function in Plugin class like this:

    – base function getPrice()
    – plugin function afterGetPrice()

    So this function code will be like this:
public function afterGetPrice(\Magento\Catalog\Model\Product $product, $price) : float
  {
    return $this->getProperPrice($price);
  }
  • around – this type of plugin provides full control over the input and output of a function. Here we can process further the original function or break that functionality. Magento recommends against using these plugins whenever possible. To create plugin around make function in Plugin class like this:

    – base function getPrice()
    – plugin function aroundGetPrice()

    Code will look like this:
public function aroundSave(\Magento\Catalog\Model\Product $product, callable $proceed)
  {
    if (true) {
    $returnValue = $proceed();
  }

    if (false) {
    $returnValue = 99;
  }

    return $returnValue;
  }

Here we have $proceed variable. If you don’t want to affect the function return function $proceed() – and the original function will be executed. If somehow you need to change functionality – return something else.

And that’s everything – remember that using plugins change data flow, and you shouldn’t use too many plugins because the order of executing all types of the plugin can be confusing.

...