How to Create And Use Plugins In Magento 2

Posted on 17 June, 2017

This technical note is about Magento 2 plugins. Here we discuss the plugin structure and how to create a plugin. A plugin is also known as Interceptors. When we hear name of the plugin in Magento 2, the first question comes in our mind that, what is a plugin and what is the use of a plugin?

What is a plugin?

A plugin, or interceptor, is a class that modifies the behavior of original public class functions or methods by another function call and running code before, after, or around that function call. This allows you to substitute or extend the behavior of original, public methods for any class or interface. Plugins only use for  "public methods".

Why use plugins?

Plugin is a interceptors approach. Its minimize confliction among extensions that change the behavior of the same class or method. Plugin class does not change class itself but it only modifies the behavior of class function. We can prevent collisions between plugins by using sort order attribute of plugin. Plugin can be called sequentially according to a sort order, so it does not conflict with other plugin class.

There are certain limitations of plugins.Plugins cannot be used with any of the following:

        - Non-public methods
        - Static methods
        - Final methods
        - Final classes
        - Virtual types
        - Any class that contains at least one final public method
        - Objects that are instantiated before Magento\Framework\Interception is bootstrapped
        - __construct

Types of plugins

  1. Before Plugin
  2. After Plugin
  3. Around Plugin

1) Before Plugin:

Before Plugin is used for changing the arguments of an original method or add some behavior before an original method called.To use before plugin, we need to use before prefix and its added to the name of an original method.The before plugin methods do not need to have a return value.

Prototype: beforeMethodname()

2) After Plugin:

After Plugin is used for changing the arguments of an original method or add some behavior before an original method called.To use after plugin, we need to use after prefix and its added to the name of an original method.The after plugin methods do not need to have a return value.

Prototype: afterMethodname()

3) Around Plugin:

After Plugin is used for changing both the arguments and returned values of an original method or add some behavior before and after an original method is called. We need to use after prefix and its added to the name of an original method.The around plugin must have a return value.

Prototype: aroundMethodname()

Declaration of a plugins

To use Plugins, first of all, we have to define it in di.xml.

1
2
3
4
5
<config>
    <type name="{ObservedType}">
      <plugin name="{pluginName}" type="{PluginClassName}" sortOrder="1" disabled="false"/>
    </type>
</config>

Type name: A class, interface, or virtual type, which is observed by a plugin.
Plugin name: A plugin name.
Plugin type: The name of a plugin’s class or virtual type.
Plugin sortOrder: Order, in which the plugins calling the same method are to be executed.
Plugin disabled: This attribute defines whether the plugin is enabled or not. disabled="true" defines the plugin is disabled.

After that define your plugin class at Vendor\Module\Plugin\ProductPlugin.php

1
2
3
4
5
6
7
8
9
10
<?php
namespace Vendor\Module\Plugin;
class ProductPlugin
{
    public function beforeSetName(\Magento\Catalog\Model\Product $subject, $name)
    {
        return ['(' . $name . ')'];
    }
}

Examples of all types of plugins.

1) Before Plugin:

In this example we will define plugin class that observed  function addProduct($productInfo, $requestInfo = null) of a Magento\Checkout\Model\Cart class. addProduct method call each and every time when we add product to cart.In this example, we will change product quantity during add to cart.

Step 1: Create di.xml at Vendor/Module/etc/di.xml.This is declaration of plugin.

1
2
3
4
5
6
<?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\Checkout\Model\Cart">
        <plugin name="productcart" type="Vendor\Module\Plugin\Productcart" sortOrder="1" />
    </type>
</config>

Step 2: Create Productcart.php as plugin class at Vendor\Module\Plugin\Productcart.php and addProduct method written as beforeAddProduct method in plugin class.

1
2
3
4
5
6
7
8
9
10
11
12
13
<?php
namespace Vendor\Module\Plugin;
class Productcart
{
public function beforeAddProduct(
    \Magento\Checkout\Model\Cart $subject,
    $productInfo,
    $requestInfo = null
){
    $requestInfo['qty'] = 5; // increasing quantity to 5
    return array($productInfo, $requestInfo);
}
}

Using this before plugin, when add to cart button clicked with 1 quantity then product will be added in cart with 5 quantity.

2) After Plugin:

In this example we will define plugin class that observed  function getName of Magento\Catalog\Model\Product class. getName() method returns product name.

Step 1: Create di.xml at Vendor/Module/etc/di.xml .This is declaration of plugin.

1
2
3
4
5
6
<?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="productname" type="Vendor\Module\Plugin\Productname" sortOrder="1" />
    </type>
</config>                    

Step 2: Create Productname.php as plugin class at Vendor\Module\Plugin\Productname.php and getName method written as afterGetName method in plugin class.

1
2
3
4
5
6
7
8
<?php
namespace Vendor\Module\Plugin;
class Productname
{
    public function afterGetName(\Magento\Catalog\Model\Product $subject, $result) {
        return "Offer ".$result; // Offer will add before Product Name
    }
}      

With this, after plugin example, we can change the product name.

3) Around Plugin:

In this example, we will define plugin class that observed function addProduct of Magento\Checkout\Model\Cart class.

Step 1: Create di.xml at Vendor/Module/etc/di.xml. This is declaration of plugin.

1
2
3
4
5
6
<?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="addPro" type="Vendor\Module\Plugin\Product" sortOrder="1" />
    </type>
</config>

Step 2: Create Product.php as plugin class at Vendor\Module\Plugin\Product.php and addProduct method written as aroundAddProduct method in plugin class.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<?php
namespace Vendor\Module\Plugin;
class Product
{
    public function aroundAddProduct(
        \Magento\Checkout\Model\Cart $subject,
        \Closure $proceed,
        $productInfo,
        $requestInfo = null
    ) {
        $requestInfo['qty'] = 5; // Increased quantity to 5
        $result = $proceed($productInfo, $requestInfo);
        // Apply logic here
        return $result;
    }
}

The return value is formed in such way that the parameters following the $proceed parameter in the around listener method definition are passed to the $proceed function call in a sequential order.

That's it, we hope this Magento technical note helped you to know how to create and use Plugin In Magento 2. Bookmark it for your future reference. Do comment below if you have any other questions or doubts.

P.S. Do share this note with your team.


Tejas Pala , eCommerce Engineer
Magento Technical Notes

Post Your Review

X

Your Review has been posted

0 Comment(s)