Search icon CANCEL
Arrow left icon
Explore Products
Best Sellers
New Releases
Books
Videos
Audiobooks
Learning Hub
Conferences
Free Learning
Arrow right icon
Arrow up icon
GO TO TOP
Magento 2 Development Quick Start Guide

You're reading from   Magento 2 Development Quick Start Guide Build better stores by extending Magento

Arrow left icon
Product type Paperback
Published in Sep 2018
Publisher Packt
ISBN-13 9781789343441
Length 218 pages
Edition 1st Edition
Languages
Tools
Concepts
Arrow right icon
Author (1):
Arrow left icon
Branko Ajzele Branko Ajzele
Author Profile Icon Branko Ajzele
Branko Ajzele
Arrow right icon
View More author details
Toc

Table of Contents (11) Chapters Close

Preface 1. Understanding the Magento Architecture FREE CHAPTER 2. Working with Entities 3. Understanding Web APIs 4. Building and Distributing Extensions 5. Developing for Admin 6. Developing for Storefront 7. Customizing Catalog Behavior 8. Customizing Checkout Experiences 9. Customizing Customer Interactions 10. Other Books You May Enjoy

Plugins

Plugins are likely one of the most powerful features of Magento. They allow us to modify the behavior of public class functions by intercepting a function call and running code before, after, or around that function call.

Before we eagerly start using them, it is worth emphasizing how plugins can't be used on the following:

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

Plugins can be used on the following:

  • Classes
  • Interfaces
  • Abstract classes
  • Parent classes

By doing a lookup for the <plugin string across the entire <MAGENTO_DIR> directory's di.xml files, we can see hundreds of plugin examples spread across the majority of Magento's modules.

The before plugin

The before plugin, as its name suggests, runs before the observed method.

When writing a before plugin, there are a few key points to remember:

  1. The before keyword is appended to the observed instance method. If the observed method is called getSomeValue, then the plugin method is called beforeGetSomeValue.
  2. The first parameter of the before plugin method is always the observed instance type, often abbreviated as $subject or directly by the class type – which is $processor in our example. We can typecast it for greater readability.
  3. All other parameters of the plugin method must match the parameters of the observed method.
  4. The plugin method must return an array with the same type and number of parameters as the observed method's input parameters.

Let's take a look at one of Magento's before plugin implementations, the one specified in the <MAGENTO_DIR>module-payment/etc/frontend/di.xml file:

<type name="Magento\Checkout\Block\Checkout\LayoutProcessor">
<plugin name="ProcessPaymentConfiguration"
type="Magento\Payment\Plugin\PaymentConfigurationProcess"/>
</type>

The original method this plugin is targeting is the process method of the Magento\Checkout\Block\Checkout\LayoutProcessor class:

public function process($jsLayout) {
// The rest of the code...
return $jsLayout;
}

The implementation of the before plugin is provided via the beforeProcess method of the Magento\Payment\Plugin\PaymentConfigurationProcess class, as per the following partial example:

public function beforeProcess(
\Magento\Checkout\Block\Checkout\LayoutProcessor $processor,
$jsLayout) {
// The rest of the code...
return [$jsLayout];
}

The around plugin

The around plugin runs around the observed method in a way that allows us to run some code before and after the original method call. This is a very powerful concept, as we get to change the incoming parameters as well as the return value of a function.

When writing the around plugin, there are a few key points to remember:

  1. The first parameter coming into the plugin is the observed type instance.
  2. The second parameter coming into the plugin is a callable/Closure. Usually, this parameter is typed and named as callable $proceed. We must make sure to forward the same parameters to this callable as the original method signature.
  3. All other parameters are parameters of the original observed method.
  4. The plugin must return the same value as the original function, ideally return $proceed(…) or $returnValue = $proceed(); followed by $returnValue; for cases where we need to modify the $returnValue.

Let's take a look at one of Magento's around plugin implementations, the one specified in the <MAGENTO_DIR>module-grouped-product/etc/di.xml file:

<type name="Magento\Catalog\Model\ResourceModel\Product\Link">
<plugin name="groupedProductLinkProcessor" type="Magento\GroupedProduct\Model\ResourceModel\Product\Link\RelationPersister" />
</type>

The original method of this plugin is targeting the deleteProductLink method of the Magento\Catalog\Model\ResourceModel\Product\Link class:

public function deleteProductLink($linkId) {
return $this->getConnection()
->delete($this->getMainTable(), ['link_id = ?' => $linkId]);
}

The implementation of the around plugin is provided via the aroundDeleteProductLink method of the Magento\GroupedProduct\Model\ResourceModel\Product\Link\RelationPersister class, as per the following partial example:

public function aroundDeleteProductLink(
\Magento\GroupedProduct\Model\ResourceModel\Product\Link $subject,
\Closure $proceed, $linkId) {
// The rest of the code...
$result = $proceed($linkId);
// The rest of the code...
return $result;
}

The after plugin

The after plugin, as its name suggests, runs after the observed method.

When writing the after plugin, there are a few key points to remember:

  1. The first parameter coming into the plugin is an observed type instance.
  2. The second parameter coming into the plugin is the result of the observed method, often called $result or called after the variable returned from the observed method (as in the following example: $data).
  3. All other parameters are parameters of the observed method.
  4. The plugin must return the same $result|$data variable of the same type, as we are free to modify the value.

Let's take a look at one of Magento's after plugin implementations, the one specified in the module-catalog/etc/di.xml file:

<type name="Magento\Indexer\Model\Config\Data">
<plugin name="indexerProductFlatConfigGet"
type="Magento\Catalog\Model\Indexer\Product\Flat\Plugin\IndexerConfigData" />
</type>

The original method this plugin is targeting is the get method of the Magento\Indexer\Model\Config\Data class:

public function get($path = null, $default = null) {
// The rest of the code...
return $data;
}

The implementation of the after plugin is provided via the afterGet method of the Magento\Catalog\Model\Indexer\Product\Flat\Plugin\IndexerConfigData class, as per the following partial example:

public function afterGet(Magento\Indexer\Model\Config\Data, $data, $path = null, $default = null) {
// The rest of the code...
return $data;
}

Special care should be taken when using plugins. While they provide great flexibility, they also make it easy to induce bugs, performance bottlenecks, and other less obvious types of instabilities – even more so if several plugins are observing the same method.

You have been reading a chapter from
Magento 2 Development Quick Start Guide
Published in: Sep 2018
Publisher: Packt
ISBN-13: 9781789343441
Register for a free Packt account to unlock a world of extra content!
A free Packt account unlocks extra newsletters, articles, discounted offers, and much more. Start advancing your knowledge today.
Unlock this book and the full library FREE for 7 days
Get unlimited access to 7000+ expert-authored eBooks and videos courses covering every tech area you can think of
Renews at €18.99/month. Cancel anytime