Close [x]

Magento plug-ins

Edit this page on GitHub

Magento plug-ins

Introduction to Magento plug-ins

Magento enables you to change, or extend, the behavior of any original, public method in any Magento class. You can change the behavior of an original method by creating an extension. These extensions use the Plugin class and are therefore referred to as plug-ins.

To ensure that plug-ins work correctly, you must follow declaration and naming rules.

You use interception to reduce conflicts among extensions that change the behavior of the same class or method. You implement interception using the Plugin class, which observes public methods, and listener methods in this class. A plug-in changes behavior of an original class, but does not change a class itself. Because they can be called sequentially, according to a configured sort order, these plug-ins do not conflict.

Interception ensures that conflicting extensions run without intervention.

Limitations

You cannot use plug-ins for:

  • Final methods / classes
  • Non-public methods
  • Class methods (such as static methods)
  • Inherited methods
  • __construct
  • Virtual types

Declare a plug-in

You declare a plugin for an object in the di.xml file for a module:

You must specify these elements:

  • type name. A class, interface, or virtual type, which the plug-in observes.
  • plugin name. An arbitrary plug-in name that identifies a plug-in. Also used to merge the configurations for the plug-in.
  • plugin type. The name of a plug-in鈥檚 class or its virtual type. Use the following schema when you specify this element: \Vendor\Module\Plugin\<ModelName>Plugin.
  • plugin sortOrder. The order in which plug-ins that call the same method are run.
  • plugin disabled. To disable a plug-in, set this element to true.

Prioritize plug-ins

Several conditions influence how plug-ins apply to the same class or interface:

  • Whether a listener method in a plug-in should apply before, after, or around an original method.

    Use one or more of the following methods to extend/modify an original method鈥檚 behavior with the interception functionality:

    • Change the arguments of an original method through the before-listener.

    • Change the values returned by an original method through the after-listener.
    • Change both the arguments and returned values of an original method through the around-listener.

      Unlike before or after, the around listener prevents the execution of the original method.

    • Override an original method (a conflicting change).

      Overriding a class is a conflicting change. Extending a class's behavior is non-conflicting change.

  • The sort order of a plug-in.

    This parameter defines the order in which the plugins that use the same type of listener and call the same method are run.

    If several plug-ins apply to the same original method, the following sequence is observed:

    • The before listener in a plug-in with the highest priority (that is, with the smallest value of sortOrder argument).
    • The around listener in a plug-in with the highest priority (that is, with the smallest value of sortOrder argument).
    • Other before listeners in plug-ins according to sort order specified for them (that is, from the smallest to the greatest value).
    • Other around listeners in plug-ins according to the sort order specified for them (that is, from the smallest to the greatest value).
    • The after listener in a plug-in with the lowest priority (that is, with the greatest value of sortOrder argument).
    • Other after listeners in plug-ins, in the reverse sort order specified for them (that is, from the greatest to the smallest value).

Example plug-ins

To change the arguments of an original method or add some behavior before an original method is called, use the before-listener method.

Prefix the name of the original method with before as the following sample shows:

<?php

namespace My\Module\Plugin;

class ProductPlugin
{
    public function beforeSetName(\Magento\Catalog\Model\Product $subject, $name)
    {
        return ['(' . $name . ')'];
    }
}

To change the values returned by an original method or add some behavior after an original method is called, use the after-listener method.

Prefix the name of the original method with after as the following sample shows:

<?php

namespace My\Module\Plugin;

class ProductPlugin
{
    public function afterGetName(\Magento\Catalog\Model\Product $subject, $result)
    {
        return '|' . $result . '|';
    }
}

To change both the arguments and returned values of an original method or add some behavior before and after an original method is called, use the around-listener method.

Prefix the name of the original listener with around as the following sample shows:

<?php

namespace My\Module\Plugin;

class ProductPlugin
{
    public function aroundSave(\Magento\Catalog\Model\Product $subject, \Closure $proceed)
    {
        $this->doSmthBeforeProductIsSaved();
        $returnValue = $proceed();
        if ($returnValue) {
            $this->postProductToFacebook();
        }
        return $returnValue;
    }
}

The around-listener method receives two parameters ($subject and $proceed), followed by the arguments belonging to an original method.

The $subject parameter provides access to all public methods of the original class.

The $proceed parameter calls the next plug-in or method.

Configuration inheritance

The configuration inheritance implies that a plug-in applied to a class or interface is derived by the classes or interfaces, which implement or inherit an original class or interface.

You can use the configuration inheritance to implement AOP-like functionality with plug-ins, for instance, to observe the same methods of all models.

You can override the plug-ins defined in the global scope by changing di.xml file of an area.