Modifying functions with the use of plugins – Interception

One of the biggest problems in Magento 1.x was that changing the behavior of a function in a class that didn't have an event trigger had to be rewritten. This works fine if only a single rewrite for a class was used, but when using a large number of extensions, there is a risk that multiple extensions rewrite the same class, which can result in unpredictable results.

In Magento 2, this problem is partly solved by introducing Interception in the form of plugins. With the use of plugins, it is possible to modify a function in three places:

  • Before execution: With the before plugin, it is possible to (pre)process any data given to the original function by modifying the original function arguments; this allows you to replace the original method or change the input variables and supply them to the original method.
  • Around execution: In the around plugin, you can modify both the input and output values of the original function. In your own function, you decide what action to do before the original function call and what will be done after it.
  • After execution: The after plugin takes the result generated from the original function, modifies the result, and the modified result is then returned to the caller of the original function.

Getting ready

The use of plugins is controlled through di.xml. It is possible to use the global from etc/ or the area specific from etc/[area]; in this case, we will use the global, which means that it is used in all areas.

How to do it…

Create the following files in this recipe to try the use of plugins:

  1. To enable the plugins, add the following lines to di.xml:

    etc/di.xml

    <type name="MagentoCmsModelPage">
      <plugin name="sample_before" type="GenmatoSamplePluginBeforePage" sortOrder="1"/>
    </type>
    
    <type name="MagentoCatalogModelProduct">
      <plugin name="sample_around" type="GenmatoSamplePluginAroundProduct" sortOrder="1"/>
    </type>
    
    <type name="MagentoCmsModelPage">
      <plugin name="sample_after" type="GenmatoSamplePluginAfterPage" sortOrder="1"/>
    </type>
  2. The following is the before plugin class:

    Plugin/BeforePage.php

    <?php
    namespace GenmatoSamplePlugin;
    
    use MagentoCmsModelPage;
    
    class BeforePage
    {
      public function beforeSetContent(Page $subject, $content)
      {
        return $subject->setContent('<!--'.$content.'-->');
      }
    }
  3. The following is the around plugin class:

    Plugin/AroundProduct.php

    <?php
    
    namespace GenmatoSamplePlugin;
    
    use MagentoCatalogModelProduct;
    
    class AroundProduct
    {
      public function aroundSave(Product $subject, Closure $proceed)
      {
        $subject->setMyCustomAttribute('sample');
    
        $return = $proceed();
    
        $subject->setMyCustomAttribute('');
    
        return $return;
      }
    }
  4. The following is the after plugin class:

    Plugin/AfterPage.php

    <?php
    namespace GenmatoSamplePlugin;
    
    use MagentoCmsModelPage;
    
    class AfterPage
    {
    
      public function afterGetTitle(Page $subject, $result)
      {
        return 'SAMPLE: '.$result;
      }
    
    }
  5. To refresh the cache, execute the following command:
    bin/magento cache:clean
    

How it works…

All configured interceptors/plugins are evaluated during initialization. When a call is made to a function that is extended through a plugin, all plugin functions are executed based on the configured sortOrder as configured in di.xml. If there are multiple plugins that extend the same original function, they are executed in the following sequence:

  1. The before plugin with the lowest sortOrder
  2. The around plugin with the lowest sortOrder
  3. Other before plugins (from the lowest to highest sortOrder)
  4. Other around plugins (from the lowest to highest sortOrder)
  5. The after plugin with the highest sortOrder
  6. Other after plugins (from the highest to lowest sortOrder)

There are some limitations on where you can use plugins; it is not possible to use plugins for the following:

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

If you need to modify one of these types listed, the only option to do this is to rewrite (preference) your class through di.xml.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.133.123.126