Magento 2

Master Magento 2 Plugins: Before, After, & Around 

Feeling stuck with customizing your Magento 2 store? Forget clunky code hacks – Magento 2 Plugins are your secret weapon! These nimble extensions let you modify existing functionality before, after, or around any method, adding superpowers to your store without breaking a sweat. Dive into this blog series and unlock the secrets of these versatile tools. We’ll guide you through plugin creation, usage, and best practices, empowering you to become a Magento 2 Plugin Master!

Introduction

What is a plugin in Magento 2 and why use it?

A plugin, also known as an interceptor, is a class that modifies the behavior of public class functions by intercepting a function call and running code before, after, or around that function call. This allows you to tailor core Magento behaviors to your specific needs without making any changes to the core code itself. This is a key advantage as it ensures that your customizations are preserved even when the platform is upgraded.

Types of plugins: before, after, and around

There are three types of plugins in Magento 2: before, after, and around. Each serves a unique purpose:

  • Before plugins: These are used to change the arguments of a function before it is executed.
  • After plugins: These are used to modify the result of a function after it has been executed.
  • Around plugins: These are used to override the original function, allowing you to run code both before and after the function execution. However, these should be used sparingly as they can affect performance and potentially conflict with other plugins.

How to declare a plugin in di.xml file

To declare a plugin in Magento 2, you need to add it to your module’s di.xml file. Here’s a basic example:

<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="myPlugin" type="Vendor\Module\Plugin\MyPlugin" sortOrder="10" disabled="false" />
    </type>
</config>

In this example, Magento\Catalog\Model\Product is the class we’re targeting, myPlugin is a unique name for our plugin, Vendor\Module\Plugin\MyPlugin is the plugin’s class, sortOrder is the order in which plugins are executed (lower numbers are executed first), and disabled determines whether the plugin is active.

Remember, plugins are a powerful tool for customizing your Magento 2 store. Use them wisely to enhance functionality and improve the user experience.

Magento 2 Before Plugin

Before plugins in Magento 2 are a type of plugin that allows you to change the arguments of a function before it is executed. This can be useful when you want to modify the behavior of a function without changing its output.

How to create a before plugin and what it does

Creating a before plugin involves two steps: declaring the plugin in your di.xml file and defining the plugin class.

Here’s how you declare a before plugin in the di.xml file:

<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="myBeforePlugin" type="Vendor\Module\Plugin\MyBeforePlugin" sortOrder="10" disabled="false" />
    </type>
</config>

In this example, myBeforePlugin is the unique name of our plugin, and Vendor\Module\Plugin\MyBeforePlugin is the plugin’s class.

Next, you define the plugin class. The method name in the plugin class is before<MethodName>, where <MethodName> is the name of the method you’re targeting. Here’s an example:

namespace Vendor\Module\Plugin;

class MyBeforePlugin
{
    public function beforeSetName(\Magento\Catalog\Model\Product $subject, $name)
    {
        return 'Before Plugin - ' . $name;
    }
}

In this example, the beforeSetName method will be called before the setName method of the Magento\Catalog\Model\Product class. The $name argument will be prefixed with ‘Before Plugin – ’ before it’s passed to the setName method.

Example: modify the input arguments of a method

Let’s say you want to modify the product names in your store to include a prefix. You could do this with a before plugin.

First, declare the plugin in your di.xml file:

<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="prefixPlugin" type="Vendor\Module\Plugin\PrefixPlugin" sortOrder="10" disabled="false" />
    </type>
</config>

Then, define the PrefixPlugin class:

namespace Vendor\Module\Plugin;

class PrefixPlugin
{
    public function beforeSetName(\Magento\Catalog\Model\Product $subject, $name)
    {
        return 'My Store - ' . $name;
    }
}

Now, whenever a product name is set, it will be prefixed with ‘My Store – ‘. For example, if you set a product’s name to ‘Awesome Product’, the before plugin will change it to ‘My Store – Awesome Product’ before it’s set. This is a simple yet powerful way to customize your store’s product names. Remember, before plugins are just one of the many tools Magento 2 provides to customize and enhance your online store. Use them wisely!

Magento 2 After Plugin

After plugins in Magento 2 allow you to modify the result of a function after it has been executed. This can be useful when you want to change the output of a function without altering its internal behavior.

How to create an after plugin and what it does

Creating an after plugin involves two steps: declaring the plugin in your di.xml file and defining the plugin class.

Here’s how you declare an after plugin in the di.xml file:

<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="myAfterPlugin" type="Vendor\Module\Plugin\MyAfterPlugin" sortOrder="10" disabled="false" />
    </type>
</config>

In this example, myAfterPlugin is the unique name of our plugin, and Vendor\Module\Plugin\MyAfterPlugin is the plugin’s class.

Next, you define the plugin class. The method name in the plugin class is after<MethodName>, where <MethodName> is the name of the method you’re targeting. Here’s an example:

namespace Vendor\Module\Plugin;

class MyAfterPlugin
{
    public function afterGetName(\Magento\Catalog\Model\Product $subject, $result)
    {
        return $result . ' - After Plugin';
    }
}

In this example, the afterGetName method will be called after the getName method of the Magento\Catalog\Model\Product class. The $result argument will be appended with ’ – After Plugin’ before it’s returned.

 Example: modify the output result of a method

Let’s say you want to modify the product names in your store to include a suffix. You could do this with an after plugin.

First, declare the plugin in your di.xml file:

<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="suffixPlugin" type="Vendor\Module\Plugin\SuffixPlugin" sortOrder="10" disabled="false" />
    </type>
</config>

Then, define the SuffixPlugin class:

namespace Vendor\Module\Plugin;

class SuffixPlugin
{
    public function afterGetName(\Magento\Catalog\Model\Product $subject, $result)
    {
        return $result . ' - My Store';
    }
}

Now, whenever a product name is retrieved, it will be suffixed with ’ – My Store’. For example, if a product’s name is ‘Awesome Product’, the after plugin will change it to ‘Awesome Product – My Store’ when it’s retrieved. This is a simple yet powerful way to customize your store’s product names. Remember, after plugins are just one of the many tools Magento 2 provides to customize and enhance your online store. Use them wisely!

Magento 2 Around Plugin

Around plugins in Magento 2 allow you to override a public method, enabling you to run custom code before and after the method call. This can be useful when you need to change the behavior of a method in more complex ways.

How to create an around plugin and what it does

Creating an around plugin involves two steps: declaring the plugin in your di.xml file and defining the plugin class.

Here’s how you declare an around plugin in the di.xml file:

<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="myAroundPlugin" type="Vendor\Module\Plugin\MyAroundPlugin" sortOrder="10" disabled="false" />
    </type>
</config>

In this example, myAroundPlugin is the unique name of our plugin, and Vendor\Module\Plugin\MyAroundPlugin is the plugin’s class.

Next, you define the plugin class. The method name in the plugin class is around<MethodName>, where <MethodName> is the name of the method you’re targeting. Here’s an example:

namespace Vendor\Module\Plugin;

class MyAroundPlugin
{
    public function aroundGetPrice(\Magento\Catalog\Model\Product $subject, callable $proceed)
    {
        echo 'Before proceed() function call';
        $result = $proceed();
        echo 'After proceed() function call';

        return $result;
    }
}

In this example, the aroundGetPrice method will be called instead of the getPrice method of the Magento\Catalog\Model\Product class. The $proceed argument is a callable that when invoked, will call the original method (or the next plugin in the chain if one exists). The echo statements will be executed before and after the original method.

 Example: execute custom logic before and after a method

Let’s say you want to log the start and end times of a method. You could do this with an around plugin.

First, declare the plugin in your di.xml file:

<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="timeLoggerPlugin" type="Vendor\Module\Plugin\TimeLoggerPlugin" sortOrder="10" disabled="false" />
    </type>
</config>

Then, define the TimeLoggerPlugin class:

namespace Vendor\Module\Plugin;

class TimeLoggerPlugin
{
    public function aroundGetPrice(\Magento\Catalog\Model\Product $subject, callable $proceed)
    {
        $startTime = microtime(true);
        $result = $proceed();
        $endTime = microtime(true);

        $executionTime = $endTime - $startTime;
        error_log('Execution time of getPrice(): ' . $executionTime . ' seconds');

        return $result;
    }
}

Now, whenever the getPrice method is called, the start and end times will be logged, and the execution time will be calculated and logged. This is a simple yet powerful way to monitor the performance of your Magento 2 store. Remember, around plugins are just one of the many tools Magento 2 provides to customize and enhance your online store. Use them wisely! However, keep in mind that around plugins should be used sparingly as they can affect performance and potentially conflict with other plugins. It’s often better to use before and after plugins if possible.

Magento 2 Plugin Execution Order

In Magento 2, the order in which plugins are executed can be controlled using the sortOrder attribute. Additionally, a plugin can be disabled using the disabled attribute. This section will explain how to use these attributes.

How to control the order of plugins using sortOrder attribute

The sortOrder attribute in the di.xml file determines the order in which plugins are executed. Plugins with lower sortOrder values are executed first. If two plugins have the same sortOrder, their execution order is determined by their load order in the configuration.

Here’s an example:

<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="firstPlugin" type="Vendor\Module\Plugin\FirstPlugin" sortOrder="10" />
        <plugin name="secondPlugin" type="Vendor\Module\Plugin\SecondPlugin" sortOrder="20" />
    </type>
</config>

In this example, firstPlugin will be executed before secondPlugin because it has a lower sortOrder value.

How to disable a plugin using disabled attribute

The disabled attribute in the di.xml file determines whether a plugin is active. If disabled is set to true, the plugin will not be executed. If disabled is set to false or omitted, the plugin will be active

Here’s an example:

<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="activePlugin" type="Vendor\Module\Plugin\ActivePlugin" disabled="false" />
        <plugin name="inactivePlugin" type="Vendor\Module\Plugin\InactivePlugin" disabled="true" />
    </type>
</config>

In this example, activePlugin will be executed, but inactivePlugin will not be executed because it is disabled.

Remember, controlling the execution order and activity of your plugins is crucial for maintaining a well-functioning Magento 2 store. Use these attributes wisely to ensure your plugins work together seamlessly. Happy coding!

Plugin’s Limitations

Plugins can not be used on following:

  • Final methods
  • Final classes
  • Non-public methods
  • Class methods (such as static methods)
  • __construct and __destruct
  • Virtual types
  • Objects that are instantiated before Magento\Framework\Interception is bootstrapped
  • Objects that implement Magento\Framework\ObjectManager\
    NoninterceptableInterface

Best Practices and Tips for Using Plugins

When working with plugins in Magento 2, it’s important to follow best practices to ensure your code is efficient, maintainable, and bug-free. This section will provide some tips and best practices for using plugins.

When to use and when not to use plugins

Plugins are a powerful tool for customizing the behavior of a Magento 2 store, but they should be used judiciously. Here are some guidelines:

  • Use plugins when: You need to modify the behavior of a public method in a class without changing the class’s source code. This is particularly useful when you want to customize core Magento functionality without risking issues during upgrades.
  • Avoid using plugins when: The class or method you want to modify is private or final, as plugins cannot be used with these. In such cases, consider using preferences or observers instead.

How to avoid conflicts and performance issues with plugins

While plugins are powerful, they can also lead to conflicts and performance issues if not used properly. Here are some tips to avoid these problems:

  • Minimize the use of around plugins: Around plugins can lead to conflicts with other plugins and can impact performance. Use before and after plugins whenever possible.
  • Use sortOrder wisely: If multiple plugins are targeting the same method, use the sortOrder attribute to control their execution order and avoid conflicts.
  • Keep your plugins lightweight: Plugins should do as little work as necessary to accomplish their goal. Heavy plugins can slow down your store and lead to a poor user experience.

How to debug and test plugins

Debugging and testing are crucial parts of the development process. Here are some tips for debugging and testing your plugins:

  • Use logging: Magento 2 has a built-in logging system that you can use to log information from your plugins. This can be invaluable for debugging.
  • Write unit tests: Unit tests can help ensure that your plugins are working as expected and can help catch issues early.
  • Test thoroughly: Make sure to test your plugins thoroughly, including edge cases. Remember, your plugins can affect the entire store, so it’s important to ensure they work correctly in all scenarios.

Remember, while plugins are a powerful tool for customization in Magento 2, they should be used wisely and responsibly. Happy coding!

Conclusion

Throughout this blog, we’ve delved into the fascinating world of Magento 2 plugins, exploring their types, functionalities, and intricacies. You’ve learned how to harness the power of before, after, and around plugins to modify inputs, outputs, and even the entire execution flow of methods. By understanding plugin execution order and best practices, you’re now equipped to leverage these extensions thoughtfully and effectively.

Remember, plugins are a powerful tool, but with great power comes responsibility. Utilize them strategically to enhance your Magento 2 store without compromising core functionality or performance. Prioritize custom-built plugins over third-party options when feasible, and always adhere to best practices for testing and debugging.

To deepen your understanding, check out these valuable resources:

Feel free to share your experiences and questions about Magento 2 Plugin in the comments below!

Leave a Reply

Your email address will not be published. Required fields are marked *